Tested on Linux-PPC64. 2016-10-26 Ville Voutilainen <ville.voutilai...@gmail.com>
Use constexpr addressof in optional, SFINAE housekeeping for any, optional and tuple. * include/std/any (__do_emplace(_Args&&...)): New. (__do_emplace(initializer_list<_Up>, _Args&&...)): Likewise. (__any_constructible): Likewise. (__any_constructible_t): Use __any_constructible. (operator=(_ValueType&&)): SFINAE in the return type. (emplace(_Args&&...)): Likewise. (emplace(initializer_list<_Up>, _Args&&...)): Likewise. * include/std/optional (_Has_addressof_mem): Remove. (_Has_addressof_free): Likewise. (_Has_addressof): Likewise. (__constexpr_addressof(_Tp&)): Likewise. (operator->): Use std::__addressof. * include/std/tuple (operator=(const tuple<_UElements...>&)): SFINAE in return type. (operator=(tuple<_UElements...>&&)): Likewise. * testsuite/20_util/any/misc/any_cast_neg.cc: Adjust.
diff --git a/libstdc++-v3/include/std/any b/libstdc++-v3/include/std/any index 45a2145..719e683 100644 --- a/libstdc++-v3/include/std/any +++ b/libstdc++-v3/include/std/any @@ -108,6 +108,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp, typename _Decayed = decay_t<_Tp>> using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; + /// Emplace with an object created from @p __args as the contained object. + template <typename _Tp, typename... _Args, + typename _Mgr = _Manager<_Tp>> + void __do_emplace(_Args&&... __args) + { + reset(); + _M_manager = &_Mgr::_S_manage; + _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); + } + + /// Emplace with an object created from @p __il and @p __args as + /// the contained object. + template <typename _Tp, typename _Up, typename... _Args, + typename _Mgr = _Manager<_Tp>> + void __do_emplace(initializer_list<_Up> __il, _Args&&... __args) + { + reset(); + _M_manager = &_Mgr::_S_manage; + _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); + } + public: // construct/destruct @@ -144,11 +165,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } + template <typename _Res, typename _Tp, typename... _Args> + using __any_constructible = + enable_if<__and_<is_copy_constructible<_Tp>, + is_constructible<_Tp, _Args...>>::value, + _Res>; + template <typename _Tp, typename... _Args> using __any_constructible_t = - enable_if_t<__and_<is_copy_constructible<_Tp>, - is_constructible<_Tp, _Args...>>::value, - bool>; + typename __any_constructible<bool, _Tp, _Args...>::type; /// Construct with a copy of @p __value as the contained object. template <typename _ValueType, typename _Tp = _Decay<_ValueType>, @@ -233,9 +258,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// Store a copy of @p __rhs as the contained object. - template<typename _ValueType, - typename _Tp = _Decay<_ValueType>> - enable_if_t<is_copy_constructible<_Tp>::value, any&> + template<typename _ValueType> + enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&> operator=(_ValueType&& __rhs) { *this = any(std::forward<_ValueType>(__rhs)); @@ -243,29 +267,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } /// Emplace with an object created from @p __args as the contained object. - template <typename _ValueType, typename... _Args, - typename _Tp = _Decay<_ValueType>, - typename _Mgr = _Manager<_Tp>, - __any_constructible_t<_Tp, _Args&&...> = false> - void emplace(_Args&&... __args) + template <typename _ValueType, typename... _Args> + typename __any_constructible<void, + _Decay<_ValueType>, _Args&&...>::type + emplace(_Args&&... __args) { - reset(); - _M_manager = &_Mgr::_S_manage; - _Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...); + __do_emplace<_Decay<_ValueType>> + (std::forward<_Args>(__args)...); } /// Emplace with an object created from @p __il and @p __args as /// the contained object. - template <typename _ValueType, typename _Up, typename... _Args, - typename _Tp = _Decay<_ValueType>, - typename _Mgr = _Manager<_Tp>, - __any_constructible_t<_Tp, initializer_list<_Up>, - _Args&&...> = false> - void emplace(initializer_list<_Up> __il, _Args&&... __args) + template <typename _ValueType, typename _Up, typename... _Args> + typename __any_constructible<void, + _Decay<_ValueType>, + initializer_list<_Up>, + _Args&&...>::type + emplace(initializer_list<_Up> __il, _Args&&... __args) { - reset(); - _M_manager = &_Mgr::_S_manage; - _Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...); + __do_emplace<_Decay<_ValueType>, _Up> + (__il, std::forward<_Args>(__args)...); } // modifiers diff --git a/libstdc++-v3/include/std/optional b/libstdc++-v3/include/std/optional index f272876..35b6932 100644 --- a/libstdc++-v3/include/std/optional +++ b/libstdc++-v3/include/std/optional @@ -96,53 +96,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_bad_optional_access(const char* __s) { _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__s)); } - template<typename _Tp, typename = void> - struct _Has_addressof_mem : std::false_type { }; - - template<typename _Tp> - struct _Has_addressof_mem<_Tp, - __void_t<decltype( std::declval<const _Tp&>().operator&() )> - > - : std::true_type { }; - - template<typename _Tp, typename = void> - struct _Has_addressof_free : std::false_type { }; - - template<typename _Tp> - struct _Has_addressof_free<_Tp, - __void_t<decltype( operator&(std::declval<const _Tp&>()) )> - > - : std::true_type { }; - - /** - * @brief Trait that detects the presence of an overloaded unary operator&. - * - * Practically speaking this detects the presence of such an operator when - * called on a const-qualified lvalue (e.g. - * declval<const _Tp&>().operator&()). - */ - template<typename _Tp> - struct _Has_addressof - : std::__or_<_Has_addressof_mem<_Tp>, _Has_addressof_free<_Tp>>::type - { }; - - /** - * @brief An overload that attempts to take the address of an lvalue as a - * constant expression. Falls back to __addressof in the presence of an - * overloaded addressof operator (unary operator&), in which case the call - * will not be a constant expression. - */ - template<typename _Tp, enable_if_t<!_Has_addressof<_Tp>::value, int>...> - constexpr _Tp* __constexpr_addressof(_Tp& __t) - { return &__t; } - - /** - * @brief Fallback overload that defers to __addressof. - */ - template<typename _Tp, enable_if_t<_Has_addressof<_Tp>::value, int>...> - inline _Tp* __constexpr_addressof(_Tp& __t) - { return std::__addressof(__t); } - /** * @brief Class template that holds the necessary state for @ref optional * and that has the responsibility for construction and the special members. @@ -681,7 +634,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Observers. constexpr const _Tp* operator->() const - { return __constexpr_addressof(this->_M_get()); } + { return std::__addressof(this->_M_get()); } _Tp* operator->() diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index c06a040..63cacd4 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -846,20 +846,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } - template<typename... _UElements, typename = typename + template<typename... _UElements> + typename enable_if<sizeof...(_UElements) - == sizeof...(_Elements)>::type> - tuple& + == sizeof...(_Elements), tuple&>::type operator=(const tuple<_UElements...>& __in) { static_cast<_Inherited&>(*this) = __in; return *this; } - template<typename... _UElements, typename = typename + template<typename... _UElements> + typename enable_if<sizeof...(_UElements) - == sizeof...(_Elements)>::type> - tuple& + == sizeof...(_Elements), tuple&>::type operator=(tuple<_UElements...>&& __in) { static_cast<_Inherited&>(*this) = std::move(__in); diff --git a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc index 8b30666..4de400d 100644 --- a/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/20_util/any/misc/any_cast_neg.cc @@ -26,5 +26,5 @@ void test01() using std::any_cast; const any y(1); - any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 432 } + any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 453 } }