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
This commit is contained in:
parent
ebd9509a2d
commit
ca9e949f2e
5 changed files with 73 additions and 78 deletions
|
@ -1,3 +1,24 @@
|
|||
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>
|
||||
|
||||
* include/bits/move.h (addressof(const _Tp&&)): Add deleted overload,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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->()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue