Re: [v3 PATCH] Cross-port the latest resolution of LWG2756 and some bug-fixes to experimental::optional.

2016-10-24 Thread Jonathan Wakely

On 22/10/16 19:39 +0300, Ville Voutilainen wrote:

On 22 October 2016 at 19:34, Ville Voutilainen
 wrote:

Cross-port the latest resolution of LWG2756 and some
bug-fixes to experimental::optional.
PR libstc++/77288
PR libstdc++/77727


And yes, I'll fix that first PR reference before committing the
ChangeLog changes. :)


OK for trunk and gcc-6-branch.




Re: [v3 PATCH] Cross-port the latest resolution of LWG2756 and some bug-fixes to experimental::optional.

2016-10-22 Thread Ville Voutilainen
On 22 October 2016 at 19:34, Ville Voutilainen
 wrote:
> Cross-port the latest resolution of LWG2756 and some
> bug-fixes to experimental::optional.
> PR libstc++/77288
> PR libstdc++/77727

And yes, I'll fix that first PR reference before committing the
ChangeLog changes. :)


[v3 PATCH] Cross-port the latest resolution of LWG2756 and some bug-fixes to experimental::optional.

2016-10-22 Thread Ville Voutilainen
Tested on Linux-x64. Ok for trunk and the gcc-6 branch?

2016-10-22  Ville Voutilainen  

Cross-port the latest resolution of LWG2756 and some
bug-fixes to experimental::optional.
PR libstc++/77288
PR libstdc++/77727
* include/experimental/optional (_Optional_base):
Remove constructors that take a _Tp.
(__is_optional_impl, __is_optional): Remove.
(__converts_from_optional): New.
(optional(_Up&&)): Fix constraints, call base with in_place.
(optional(const optional<_Up>&)): Fix constraints, use emplace.
(optional(optional<_Up>&&)): Likewise.
(operator=(_Up&&)): Fix constraints.
(operator=(const optional<_Up>&)): Likewise.
(operator=(optional<_Up>&&)): Likewise.
(emplace(_Args&&...)): Constrain.
(emplace(initializer_list<_Up>, _Args&&...)): Likewise.
* testsuite/experimental/optional/77288.cc: New.
* testsuite/experimental/optional/assignment/5.cc: Adjust.
* testsuite/experimental/optional/cons/77727.cc: New.
* testsuite/experimental/optional/cons/value.cc: Adjust.
diff --git a/libstdc++-v3/include/experimental/optional 
b/libstdc++-v3/include/experimental/optional
index 7191eca..a631158 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -214,12 +214,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   : _Optional_base{} { }
 
   // Constructors for engaged optionals.
-  constexpr _Optional_base(const _Tp& __t)
-  : _M_payload(__t), _M_engaged(true) { }
-
-  constexpr _Optional_base(_Tp&& __t)
-  : _M_payload(std::move(__t)), _M_engaged(true) { }
-
   template
 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
@@ -356,12 +350,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr _Optional_base(nullopt_t) noexcept
   : _Optional_base{} { }
 
-  constexpr _Optional_base(const _Tp& __t)
-  : _M_payload(__t), _M_engaged(true) { }
-
-  constexpr _Optional_base(_Tp&& __t)
-  : _M_payload(std::move(__t)), _M_engaged(true) { }
-
   template
 constexpr explicit _Optional_base(in_place_t, _Args&&... __args)
 : _M_payload(std::forward<_Args>(__args)...), _M_engaged(true) { }
@@ -474,19 +462,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
   class optional;
 
-  template
-struct __is_optional_impl : false_type
-{ };
-
-  template
-  struct __is_optional_impl> : true_type
-{ };
-
-  template
-struct __is_optional
-: public __is_optional_impl>>
-{ };
-
+  template
+using __converts_from_optional =
+  __or_&>,
+   is_constructible<_Tp, optional<_Up>&>,
+   is_constructible<_Tp, const optional<_Up>&&>,
+   is_constructible<_Tp, optional<_Up>&&>,
+   is_convertible&, _Tp>,
+   is_convertible&, _Tp>,
+   is_convertible&&, _Tp>,
+   is_convertible&&, _Tp>>;
+
+  template
+using __assigns_from_optional =
+  __or_&>,
+   is_assignable<_Tp&, optional<_Up>&>,
+   is_assignable<_Tp&, const optional<_Up>&&>,
+   is_assignable<_Tp&, optional<_Up>&&>>;
 
   /**
 * @brief Class template for optional values.
@@ -522,75 +514,75 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr optional() = default;
   // Converting constructors for engaged optionals.
-  template >,
+ __not_, decay_t<_Up>>>,
  is_constructible<_Tp, _Up&&>,
  is_convertible<_Up&&, _Tp>
  >::value, bool> = true>
   constexpr optional(_Up&& __t)
-: _Base(_Tp(std::forward<_Up>(__t))) { }
+: _Base(in_place, std::forward<_Up>(__t)) { }
 
-  template >,
-   is_constructible<_Tp, _Up&&>,
-   __not_>
-   >::value, bool> = false>
+ __not_, decay_t<_Up>>>,
+ is_constructible<_Tp, _Up&&>,
+ __not_>
+ >::value, bool> = false>
   explicit constexpr optional(_Up&& __t)
-: _Base(_Tp(std::forward<_Up>(__t))) { }
+: _Base(in_place, std::forward<_Up>(__t)) { }
 
   template >,
-   __not_&>>,
-   __not_&, _Tp>>,
is_constructible<_Tp, const _Up&>,
-   is_convertible
+