In C++1z drafts up to N4606 the constexpr keyword was missing from the
detailed description of this function, despite being shown in the class
synopsis.  That was fixed editorially for N4618, but our implementation
was not corrected to match.

        * include/std/optional (optional::value_or(U&&) &&): Add missing
        constexpr specifier.
        * testsuite/20_util/optional/constexpr/observers/4.cc: Check value_or
        for disengaged optionals and rvalue optionals.
        * testsuite/20_util/optional/observers/4.cc: Likewise.

Tested powerpc64le-linux, committed to trunk.

I will backport this to gcc-8-branch too.

commit ce471593e4ce944807efad1d0fa7ed5d0a53da1e
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Apr 17 13:57:14 2019 +0100

    Add constexpr to std::optional::value_or(U&&)&&
    
    In C++1z drafts up to N4606 the constexpr keyword was missing from the
    detailed description of this function, despite being shown in the class
    synopsis.  That was fixed editorially for N4618, but our implementation
    was not corrected to match.
    
            * include/std/optional (optional::value_or(U&&) &&): Add missing
            constexpr specifier.
            * testsuite/20_util/optional/constexpr/observers/4.cc: Check 
value_or
            for disengaged optionals and rvalue optionals.
            * testsuite/20_util/optional/observers/4.cc: Likewise.

diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index d243930fed4..503d859bee6 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -959,7 +959,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
 
       template<typename _Up>
-       _Tp
+       constexpr _Tp
        value_or(_Up&& __u) &&
        {
          static_assert(is_move_constructible_v<_Tp>);
diff --git a/libstdc++-v3/testsuite/20_util/optional/constexpr/observers/4.cc 
b/libstdc++-v3/testsuite/20_util/optional/constexpr/observers/4.cc
index 1f7f0e8b6a2..a085f53f8fa 100644
--- a/libstdc++-v3/testsuite/20_util/optional/constexpr/observers/4.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/constexpr/observers/4.cc
@@ -25,10 +25,42 @@ struct value_type
   int i;
 };
 
-int main()
+void test01()
 {
   constexpr std::optional<value_type> o { value_type { 51 } };
   constexpr value_type fallback { 3 };
-  static_assert( o.value_or(fallback).i == 51, "" );
-  static_assert( o.value_or(fallback).i == (*o).i, "" );
+  static_assert( o.value_or(fallback).i == 51 );
+  static_assert( o.value_or(fallback).i == (*o).i );
+}
+
+void test02()
+{
+  constexpr std::optional<value_type> o;
+  constexpr value_type fallback { 3 };
+  static_assert( o.value_or(fallback).i == 3 );
+}
+
+template<typename T>
+  constexpr std::optional<value_type>
+  make_rvalue(T t)
+  { return std::optional<value_type>{t}; }
+
+void test03()
+{
+  constexpr value_type fallback { 3 };
+  static_assert( make_rvalue(value_type{51}).value_or(fallback).i == 51 );
+}
+
+void test04()
+{
+  constexpr value_type fallback { 3 };
+  static_assert( make_rvalue(std::nullopt).value_or(fallback).i == 3 );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
 }
diff --git a/libstdc++-v3/testsuite/20_util/optional/observers/4.cc 
b/libstdc++-v3/testsuite/20_util/optional/observers/4.cc
index c24e4e6856e..5d608cdeaf7 100644
--- a/libstdc++-v3/testsuite/20_util/optional/observers/4.cc
+++ b/libstdc++-v3/testsuite/20_util/optional/observers/4.cc
@@ -26,10 +26,42 @@ struct value_type
   int i;
 };
 
-int main()
+void test01()
 {
   std::optional<value_type> o { value_type { 51 } };
   value_type fallback { 3 };
   VERIFY( o.value_or(fallback).i == 51 );
   VERIFY( o.value_or(fallback).i == (*o).i );
 }
+
+void test02()
+{
+  std::optional<value_type> o;
+  value_type fallback { 3 };
+  VERIFY( o.value_or(fallback).i == 3 );
+}
+
+void test03()
+{
+  std::optional<value_type> o { value_type { 51 } };
+  value_type fallback { 3 };
+  VERIFY( std::move(o).value_or(fallback).i == 51 );
+  VERIFY( o.has_value() );
+  VERIFY( std::move(o).value_or(fallback).i == (*o).i );
+}
+
+void test04()
+{
+  std::optional<value_type> o;
+  value_type fallback { 3 };
+  VERIFY( std::move(o).value_or(fallback).i == 3 );
+  VERIFY( !o.has_value() );
+}
+
+int main()
+{
+  test01();
+  test02();
+  test03();
+  test04();
+}

Reply via email to