Commit ca9e949f by Ville Voutilainen Committed by Ville Voutilainen

Use constexpr addressof in optional, SFINAE housekeeping for any, optional and tuple.

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.

From-SVN: r242390
parent ebd9509a
2016-11-14 Ville Voutilainen <ville.voutilainen@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.
2016-11-14 Jonathan Wakely <jwakely@redhat.com> 2016-11-14 Jonathan Wakely <jwakely@redhat.com>
* include/bits/move.h (addressof(const _Tp&&)): Add deleted overload, * include/bits/move.h (addressof(const _Tp&&)): Add deleted overload,
......
...@@ -108,6 +108,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -108,6 +108,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Decayed = decay_t<_Tp>> template<typename _Tp, typename _Decayed = decay_t<_Tp>>
using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>; 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: public:
// construct/destruct // construct/destruct
...@@ -144,11 +165,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -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> template <typename _Tp, typename... _Args>
using __any_constructible_t = using __any_constructible_t =
enable_if_t<__and_<is_copy_constructible<_Tp>, typename __any_constructible<bool, _Tp, _Args...>::type;
is_constructible<_Tp, _Args...>>::value,
bool>;
/// Construct with a copy of @p __value as the contained object. /// Construct with a copy of @p __value as the contained object.
template <typename _ValueType, typename _Tp = _Decay<_ValueType>, template <typename _ValueType, typename _Tp = _Decay<_ValueType>,
...@@ -233,9 +258,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -233,9 +258,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// Store a copy of @p __rhs as the contained object. /// Store a copy of @p __rhs as the contained object.
template<typename _ValueType, template<typename _ValueType>
typename _Tp = _Decay<_ValueType>> enable_if_t<is_copy_constructible<_Decay<_ValueType>>::value, any&>
enable_if_t<is_copy_constructible<_Tp>::value, any&>
operator=(_ValueType&& __rhs) operator=(_ValueType&& __rhs)
{ {
*this = any(std::forward<_ValueType>(__rhs)); *this = any(std::forward<_ValueType>(__rhs));
...@@ -243,29 +267,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -243,29 +267,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// Emplace with an object created from @p __args as the contained object. /// Emplace with an object created from @p __args as the contained object.
template <typename _ValueType, typename... _Args, template <typename _ValueType, typename... _Args>
typename _Tp = _Decay<_ValueType>, typename __any_constructible<void,
typename _Mgr = _Manager<_Tp>, _Decay<_ValueType>, _Args&&...>::type
__any_constructible_t<_Tp, _Args&&...> = false> emplace(_Args&&... __args)
void emplace(_Args&&... __args)
{ {
reset(); __do_emplace<_Decay<_ValueType>>
_M_manager = &_Mgr::_S_manage; (std::forward<_Args>(__args)...);
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
} }
/// Emplace with an object created from @p __il and @p __args as /// Emplace with an object created from @p __il and @p __args as
/// the contained object. /// the contained object.
template <typename _ValueType, typename _Up, typename... _Args, template <typename _ValueType, typename _Up, typename... _Args>
typename _Tp = _Decay<_ValueType>, typename __any_constructible<void,
typename _Mgr = _Manager<_Tp>, _Decay<_ValueType>,
__any_constructible_t<_Tp, initializer_list<_Up>, initializer_list<_Up>,
_Args&&...> = false> _Args&&...>::type
void emplace(initializer_list<_Up> __il, _Args&&... __args) emplace(initializer_list<_Up> __il, _Args&&... __args)
{ {
reset(); __do_emplace<_Decay<_ValueType>, _Up>
_M_manager = &_Mgr::_S_manage; (__il, std::forward<_Args>(__args)...);
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
} }
// modifiers // modifiers
......
...@@ -96,53 +96,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -96,53 +96,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__throw_bad_optional_access(const char* __s) __throw_bad_optional_access(const char* __s)
{ _GLIBCXX_THROW_OR_ABORT(bad_optional_access(__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 * @brief Class template that holds the necessary state for @ref optional
* and that has the responsibility for construction and the special members. * and that has the responsibility for construction and the special members.
...@@ -681,7 +634,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -681,7 +634,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Observers. // Observers.
constexpr const _Tp* constexpr const _Tp*
operator->() const operator->() const
{ return __constexpr_addressof(this->_M_get()); } { return std::__addressof(this->_M_get()); }
_Tp* _Tp*
operator->() operator->()
......
...@@ -846,20 +846,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -846,20 +846,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this; return *this;
} }
template<typename... _UElements, typename = typename template<typename... _UElements>
typename
enable_if<sizeof...(_UElements) enable_if<sizeof...(_UElements)
== sizeof...(_Elements)>::type> == sizeof...(_Elements), tuple&>::type
tuple&
operator=(const tuple<_UElements...>& __in) operator=(const tuple<_UElements...>& __in)
{ {
static_cast<_Inherited&>(*this) = __in; static_cast<_Inherited&>(*this) = __in;
return *this; return *this;
} }
template<typename... _UElements, typename = typename template<typename... _UElements>
typename
enable_if<sizeof...(_UElements) enable_if<sizeof...(_UElements)
== sizeof...(_Elements)>::type> == sizeof...(_Elements), tuple&>::type
tuple&
operator=(tuple<_UElements...>&& __in) operator=(tuple<_UElements...>&& __in)
{ {
static_cast<_Inherited&>(*this) = std::move(__in); static_cast<_Inherited&>(*this) = std::move(__in);
......
...@@ -26,5 +26,5 @@ void test01() ...@@ -26,5 +26,5 @@ void test01()
using std::any_cast; using std::any_cast;
const any y(1); const any y(1);
any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 432 } any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 453 }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment