diff options
Diffstat (limited to 'libstdc++-v3/include/std/tuple')
-rw-r--r-- | libstdc++-v3/include/std/tuple | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 17c82049030..180a34629f8 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -48,7 +48,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal> + template<typename... _Elements> + class tuple; + + template<typename _Tp> + struct __is_empty_non_tuple : is_empty<_Tp> { }; + + // Using EBO for elements that are tuples causes ambiguous base errors. + template<typename _El0, typename... _El> + struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; + + // Use the Empty Base-class Optimization for empty, non-final types. + template<typename _Tp> + using __empty_not_final + = typename conditional<__is_final(_Tp), false_type, + __is_empty_non_tuple<_Tp>>::type; + + template<std::size_t _Idx, typename _Head, + bool = __empty_not_final<_Head>::value> struct _Head_base; template<std::size_t _Idx, typename _Head> @@ -156,20 +173,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * get() operation. */ template<std::size_t _Idx, typename... _Elements> - struct _Tuple_impl; - - template<typename _Tp> - struct __is_empty_non_tuple : is_empty<_Tp> { }; - - // Using EBO for elements that are tuples causes ambiguous base errors. - template<typename _El0, typename... _El> - struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; - - // Use the Empty Base-class Optimization for empty, non-final types. - template<typename _Tp> - using __empty_not_final - = typename conditional<__is_final(_Tp), false_type, - __is_empty_non_tuple<_Tp>>::type; + struct _Tuple_impl; /** * Recursive tuple implementation. Here we store the @c Head element @@ -179,14 +183,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<std::size_t _Idx, typename _Head, typename... _Tail> struct _Tuple_impl<_Idx, _Head, _Tail...> : public _Tuple_impl<_Idx + 1, _Tail...>, - private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> + private _Head_base<_Idx, _Head> { template<std::size_t, typename...> friend class _Tuple_impl; typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; - typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; + typedef _Head_base<_Idx, _Head> _Base; - static constexpr _Head& + static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } static constexpr const _Head& @@ -201,12 +205,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _Tuple_impl() : _Inherited(), _Base() { } - explicit + explicit constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) : _Inherited(__tail...), _Base(__head) { } template<typename _UHead, typename... _UTail, typename = typename - enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> + enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> explicit constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) : _Inherited(std::forward<_UTail>(__tail)...), @@ -218,7 +222,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tuple_impl(_Tuple_impl&& __in) noexcept(__and_<is_nothrow_move_constructible<_Head>, is_nothrow_move_constructible<_Inherited>>::value) - : _Inherited(std::move(_M_tail(__in))), + : _Inherited(std::move(_M_tail(__in))), _Base(std::forward<_Head>(_M_head(__in))) { } template<typename... _UElements> @@ -256,13 +260,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, const _Tuple_impl& __in) - : _Inherited(__tag, __a, _M_tail(__in)), + : _Inherited(__tag, __a, _M_tail(__in)), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } template<typename _Alloc> _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, _Tuple_impl&& __in) - : _Inherited(__tag, __a, std::move(_M_tail(__in))), + : _Inherited(__tag, __a, std::move(_M_tail(__in))), _Base(__use_alloc<_Head, _Alloc, _Head>(__a), std::forward<_Head>(_M_head(__in))) { } @@ -336,11 +340,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Basis case of inheritance recursion. template<std::size_t _Idx, typename _Head> struct _Tuple_impl<_Idx, _Head> - : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> + : private _Head_base<_Idx, _Head> { template<std::size_t, typename...> friend class _Tuple_impl; - typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; + typedef _Head_base<_Idx, _Head> _Base; static constexpr _Head& _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } @@ -457,9 +461,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; - template<typename... _Elements> - class tuple; - // Concept utility functions, reused in conditionally-explicit // constructors. template<bool, typename... _Elements> @@ -550,7 +551,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; /// Primary class template, tuple - template<typename... _Elements> + template<typename... _Elements> class tuple : public _Tuple_impl<0, _Elements...> { typedef _Tuple_impl<0, _Elements...> _Inherited; @@ -657,7 +658,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr tuple(const tuple&) = default; - constexpr tuple(tuple&&) = default; + constexpr tuple(tuple&&) = default; // Shortcut for the cases where constructors taking tuples // must avoid creating temporaries. @@ -876,6 +877,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: void swap(tuple&) noexcept { /* no-op */ } + // We need the default since we're going to define no-op + // allocator constructors. + tuple() = default; + // No-op allocator constructors. + template<typename _Alloc> + tuple(allocator_arg_t, const _Alloc&) { } + template<typename _Alloc> + tuple(allocator_arg_t, const _Alloc&, const tuple&) { } }; /// Partial specialization, 2-element tuple. @@ -1330,7 +1339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return bool(std::get<__i>(__t) == std::get<__i>(__u)) && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); } - + static constexpr bool __less(const _Tp& __t, const _Up& __u) { @@ -1345,7 +1354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { static constexpr bool __eq(const _Tp&, const _Up&) { return true; } - + static constexpr bool __less(const _Tp&, const _Up&) { return false; } }; @@ -1560,7 +1569,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// swap template<typename... _Elements> - inline void + inline +#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 + // Constrained free swap overload, see p0185r1 + typename enable_if<__and_<__is_swappable<_Elements>...>::value + >::type +#else + void +#endif swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } |