[libcxx] r300140 - [libcxx] Fix __compressed_pair so it doesn't copy the argument multiple times, and add constexpr.
Lang Hames via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 24 15:02:03 PDT 2017
Hi Eric,
Renaming __compressed_pair_elem's member from __first_ to __value_ has
broken a lot of LLDB's data formatters. Would it be possible to rename it
back for consistency? If it's just a rename it would be preferable to the
alternative, which would be to add some clumsy fallback logic in LLDB:
if (auto *Entry = find_element("__first_"))
// ...
else if (auto *Entry = find_element("__value_"))
// ...
else
// ...
Cheers,
Lang.
On Wed, Apr 12, 2017 at 4:45 PM, Eric Fiselier via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: ericwf
> Date: Wed Apr 12 18:45:53 2017
> New Revision: 300140
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300140&view=rev
> Log:
> [libcxx] Fix __compressed_pair so it doesn't copy the argument multiple
> times, and add constexpr.
>
> Summary:
> __compressed_pair takes and passes it's constructor arguments by value.
> This causes arguments to be moved 3 times instead of once. This patch
> addresses that issue and fixes `constexpr` on the constructors.
>
> I would rather have this fix than D27564, and I'm fairly confident it's
> not ABI breaking but I'm not 100% sure.
>
> I prefer this solution because it removes a lot of code and makes the
> implementation *much* smaller.
>
> Reviewers: mclow.lists, K-ballo
>
> Reviewed By: K-ballo
>
> Subscribers: K-ballo, cfe-commits
>
> Differential Revision: https://reviews.llvm.org/D27565
>
> Modified:
> libcxx/trunk/include/__hash_table
> libcxx/trunk/include/memory
> libcxx/trunk/include/string
> libcxx/trunk/test/std/utilities/memory/unique.ptr/
> unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
>
> Modified: libcxx/trunk/include/__hash_table
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/_
> _hash_table?rev=300140&r1=300139&r2=300140&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/__hash_table (original)
> +++ libcxx/trunk/include/__hash_table Wed Apr 12 18:45:53 2017
> @@ -1402,7 +1402,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>
> const key_equal&
> __eql,
> const
> allocator_type& __a)
> : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a),
> 0)),
> - __p1_(__node_allocator(__a)),
> + __p1_(__second_tag(), __node_allocator(__a)),
> __p2_(0, __hf),
> __p3_(1.0f, __eql)
> {
> @@ -1411,7 +1411,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>
> template <class _Tp, class _Hash, class _Equal, class _Alloc>
> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const
> allocator_type& __a)
> : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a),
> 0)),
> - __p1_(__node_allocator(__a)),
> + __p1_(__second_tag(), __node_allocator(__a)),
> __p2_(0),
> __p3_(1.0f)
> {
> @@ -1423,7 +1423,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>
> __bucket_list_deleter(allocator_traits<__pointer_allocator>::
> select_on_container_copy_construction(
> __u.__bucket_list_.get_deleter().__alloc()), 0)),
> - __p1_(allocator_traits<__node_allocator>::
> + __p1_(__second_tag(), allocator_traits<__node_allocator>::
> select_on_container_copy_construction(__u.__node_alloc())),
> __p2_(0, __u.hash_function()),
> __p3_(__u.__p3_)
> @@ -1434,7 +1434,7 @@ template <class _Tp, class _Hash, class
> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const
> __hash_table& __u,
> const
> allocator_type& __a)
> : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a),
> 0)),
> - __p1_(__node_allocator(__a)),
> + __p1_(__second_tag(), __node_allocator(__a)),
> __p2_(0, __u.hash_function()),
> __p3_(__u.__p3_)
> {
> @@ -1468,7 +1468,7 @@ template <class _Tp, class _Hash, class
> __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&&
> __u,
> const
> allocator_type& __a)
> : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a),
> 0)),
> - __p1_(__node_allocator(__a)),
> + __p1_(__second_tag(), __node_allocator(__a)),
> __p2_(0, _VSTD::move(__u.hash_function())),
> __p3_(_VSTD::move(__u.__p3_))
> {
>
> Modified: libcxx/trunk/include/memory
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/
> memory?rev=300140&r1=300139&r2=300140&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/memory (original)
> +++ libcxx/trunk/include/memory Wed Apr 12 18:45:53 2017
> @@ -653,7 +653,7 @@ void* align(size_t alignment, size_t siz
> #include <tuple>
> #include <stdexcept>
> #include <cstring>
> -
> +#include <cassert>
> #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
> # include <atomic>
> #endif
> @@ -2070,307 +2070,174 @@ public:
> };
> #endif
>
> -template <class _T1, class _T2, bool = is_same<typename
> remove_cv<_T1>::type,
> - typename
> remove_cv<_T2>::type>::value,
> - bool = is_empty<_T1>::value
> - && !__libcpp_is_final<_T1>::value,
> - bool = is_empty<_T2>::value
> - && !__libcpp_is_final<_T2>::value
> - >
> -struct __libcpp_compressed_pair_switch;
> -
> -template <class _T1, class _T2, bool IsSame>
> -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, false>
> {enum {value = 0};};
> +template <class _Tp, int _Idx,
> + bool _CanBeEmptyBase =
> + is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
> +struct __compressed_pair_elem {
> + typedef _Tp _ParamT;
> + typedef _Tp& reference;
> + typedef const _Tp& const_reference;
>
> -template <class _T1, class _T2, bool IsSame>
> -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, true, false>
> {enum {value = 1};};
> -
> -template <class _T1, class _T2, bool IsSame>
> -struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, true>
> {enum {value = 2};};
> -
> -template <class _T1, class _T2>
> -struct __libcpp_compressed_pair_switch<_T1, _T2, false, true, true>
> {enum {value = 3};};
> +#ifndef _LIBCPP_CXX03_LANG
> + __compressed_pair_elem() = default;
>
> -template <class _T1, class _T2>
> -struct __libcpp_compressed_pair_switch<_T1, _T2, true, true, true>
> {enum {value = 1};};
> + template <class _Up, class = typename enable_if<
> + !is_same<__compressed_pair_elem,
> _Up>::value>::type>
> + _LIBCPP_CONSTEXPR explicit
> + __compressed_pair_elem(_Up&& __u)
> + : __value_(_VSTD::forward<_Up>(__u)){};
> +
> + template <class... _Args, size_t... _Indexes>
> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
> + __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
> + __tuple_indices<_Indexes...>)
> + : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...)
> {}
> +#else
> + __compressed_pair_elem() : __value_() {}
> + __compressed_pair_elem(_ParamT __p) : __value_(std::forward<_ParamT>(__p))
> {}
> +#endif
>
> -template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1,
> _T2>::value>
> -class __libcpp_compressed_pair_imp;
> + reference __get() _NOEXCEPT { return __value_; }
> + const_reference __get() const _NOEXCEPT { return __value_; }
>
> -template <class _T1, class _T2>
> -class __libcpp_compressed_pair_imp<_T1, _T2, 0>
> -{
> private:
> - _T1 __first_;
> - _T2 __second_;
> -public:
> - typedef _T1 _T1_param;
> - typedef _T2 _T2_param;
> -
> - typedef typename remove_reference<_T1>::type& _T1_reference;
> - typedef typename remove_reference<_T2>::type& _T2_reference;
> -
> - typedef typename remove_reference<typename
> add_const<_T1>::type>::type& _T1_const_reference;
> - typedef typename remove_reference<typename
> add_const<_T2>::type>::type& _T2_const_reference;
> -
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() :
> __first_(), __second_() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param
> __t1)
> - : __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param
> __t2)
> - : __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {}
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param
> __t1, _T2_param __t2)
> - : __first_(_VSTD::forward<_T1_param>(__t1)),
> __second_(_VSTD::forward<_T2_param>(__t2)) {}
> -
> -#ifndef _LIBCPP_HAS_NO_VARIADICS
> -
> - template <class... _Args1, class... _Args2, size_t... _I1, size_t...
> _I2>
> - _LIBCPP_INLINE_VISIBILITY
> - __libcpp_compressed_pair_imp(piecewise_construct_t,
> - tuple<_Args1...> __first_args,
> - tuple<_Args2...> __second_args,
> - __tuple_indices<_I1...>,
> - __tuple_indices<_I2...>)
> - : __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__
> first_args))...),
> - __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__
> second_args))...)
> - {}
> -
> -#endif // _LIBCPP_HAS_NO_VARIADICS
> -
> - _LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT
> {return __first_;}
> - _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT
> {return __first_;}
> -
> - _LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT
> {return __second_;}
> - _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const
> _NOEXCEPT {return __second_;}
> -
> - _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&
> __x)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {
> - using _VSTD::swap;
> - swap(__first_, __x.__first_);
> - swap(__second_, __x.__second_);
> - }
> + _Tp __value_;
> };
>
> -template <class _T1, class _T2>
> -class __libcpp_compressed_pair_imp<_T1, _T2, 1>
> - : private _T1
> -{
> -private:
> - _T2 __second_;
> -public:
> - typedef _T1 _T1_param;
> - typedef _T2 _T2_param;
> -
> - typedef _T1& _T1_reference;
> - typedef typename remove_reference<_T2>::type& _T2_reference;
> +template <class _Tp, int _Idx>
> +struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
> + typedef _Tp _ParamT;
> + typedef _Tp& reference;
> + typedef const _Tp& const_reference;
> + typedef _Tp __value_type;
>
> - typedef const _T1&
> _T1_const_reference;
> - typedef typename remove_reference<typename
> add_const<_T2>::type>::type&
> - _T2_const_reference;
> -
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() :
> __second_() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param
> __t1)
> - : _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param
> __t2)
> - : __second_(_VSTD::forward<_T2_param>(__t2)) {}
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param
> __t1, _T2_param __t2)
> - : _T1(_VSTD::forward<_T1_param>(__t1)),
> __second_(_VSTD::forward<_T2_param>(__t2)) {}
> -
> -#ifndef _LIBCPP_HAS_NO_VARIADICS
> -
> - template <class... _Args1, class... _Args2, size_t... _I1, size_t...
> _I2>
> - _LIBCPP_INLINE_VISIBILITY
> - __libcpp_compressed_pair_imp(piecewise_construct_t,
> - tuple<_Args1...> __first_args,
> - tuple<_Args2...> __second_args,
> - __tuple_indices<_I1...>,
> - __tuple_indices<_I2...>)
> - : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args)).
> ..),
> - __second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__
> second_args))...)
> - {}
> -
> -#endif // _LIBCPP_HAS_NO_VARIADICS
> -
> - _LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT
> {return *this;}
> - _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT
> {return *this;}
> +#ifndef _LIBCPP_CXX03_LANG
> + __compressed_pair_elem() = default;
>
> - _LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT
> {return __second_;}
> - _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const
> _NOEXCEPT {return __second_;}
> + template <class _Up, class = typename enable_if<
> + !is_same<__compressed_pair_elem,
> _Up>::value>::type>
> + _LIBCPP_CONSTEXPR explicit
> + __compressed_pair_elem(_Up&& __u)
> + : __value_type(_VSTD::forward<_Up>(__u)){};
> +
> + template <class... _Args, size_t... _Indexes>
> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
> + __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
> + __tuple_indices<_Indexes...>)
> + : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...)
> {}
> +#else
> + __compressed_pair_elem() : __value_type() {}
> + __compressed_pair_elem(_ParamT __p)
> + : __value_type(std::forward<_ParamT>(__p)) {}
> +#endif
>
> - _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&
> __x)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {
> - using _VSTD::swap;
> - swap(__second_, __x.__second_);
> - }
> + reference __get() _NOEXCEPT { return *this; }
> + const_reference __get() const _NOEXCEPT { return *this; }
> };
>
> -template <class _T1, class _T2>
> -class __libcpp_compressed_pair_imp<_T1, _T2, 2>
> - : private _T2
> -{
> -private:
> - _T1 __first_;
> -public:
> - typedef _T1 _T1_param;
> - typedef _T2 _T2_param;
> -
> - typedef typename remove_reference<_T1>::type& _T1_reference;
> - typedef _T2& _T2_reference;
> -
> - typedef typename remove_reference<typename
> add_const<_T1>::type>::type&
> - _T1_const_reference;
> - typedef const _T2&
> _T2_const_reference;
> -
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_()
> {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param
> __t1)
> - : __first_(_VSTD::forward<_T1_param>(__t1)) {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param
> __t2)
> - : _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {}
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param
> __t1, _T2_param __t2)
> - _NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
> - is_nothrow_move_constructible<_T2>::value)
> - : _T2(_VSTD::forward<_T2_param>(__t2)),
> __first_(_VSTD::forward<_T1_param>(__t1)) {}
> -
> -#ifndef _LIBCPP_HAS_NO_VARIADICS
> -
> - template <class... _Args1, class... _Args2, size_t... _I1, size_t...
> _I2>
> - _LIBCPP_INLINE_VISIBILITY
> - __libcpp_compressed_pair_imp(piecewise_construct_t,
> - tuple<_Args1...> __first_args,
> - tuple<_Args2...> __second_args,
> - __tuple_indices<_I1...>,
> - __tuple_indices<_I2...>)
> - : _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))
> ...),
> - __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__
> first_args))...)
> -
> - {}
> -
> -#endif // _LIBCPP_HAS_NO_VARIADICS
> -
> - _LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT
> {return __first_;}
> - _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT
> {return __first_;}
> -
> - _LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT
> {return *this;}
> - _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const
> _NOEXCEPT {return *this;}
> -
> - _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&
> __x)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {
> - using _VSTD::swap;
> - swap(__first_, __x.__first_);
> - }
> -};
> +// Tag used to construct the second element of the compressed pair.
> +struct __second_tag {};
>
> template <class _T1, class _T2>
> -class __libcpp_compressed_pair_imp<_T1, _T2, 3>
> - : private _T1,
> - private _T2
> -{
> -public:
> - typedef _T1 _T1_param;
> - typedef _T2 _T2_param;
> -
> - typedef _T1& _T1_reference;
> - typedef _T2& _T2_reference;
> -
> - typedef const _T1& _T1_const_reference;
> - typedef const _T2& _T2_const_reference;
> -
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param
> __t1)
> - : _T1(_VSTD::forward<_T1_param>(__t1)) {}
> - _LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param
> __t2)
> - : _T2(_VSTD::forward<_T2_param>(__t2)) {}
> - _LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param
> __t1, _T2_param __t2)
> - : _T1(_VSTD::forward<_T1_param>(__t1)),
> _T2(_VSTD::forward<_T2_param>(__t2)) {}
> -
> -#ifndef _LIBCPP_HAS_NO_VARIADICS
> -
> - template <class... _Args1, class... _Args2, size_t... _I1, size_t...
> _I2>
> - _LIBCPP_INLINE_VISIBILITY
> - __libcpp_compressed_pair_imp(piecewise_construct_t,
> - tuple<_Args1...> __first_args,
> - tuple<_Args2...> __second_args,
> - __tuple_indices<_I1...>,
> - __tuple_indices<_I2...>)
> - : _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args)).
> ..),
> - _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))
> ...)
> - {}
> +class __compressed_pair : private __compressed_pair_elem<_T1, 0>,
> + private __compressed_pair_elem<_T2, 1> {
> + typedef __compressed_pair_elem<_T1, 0> _Base1;
> + typedef __compressed_pair_elem<_T2, 1> _Base2;
> +
> + // NOTE: This static assert should never fire because __compressed_pair
> + // is *almost never* used in a scenario where it's possible for T1 ==
> T2.
> + // (The exception is std::function where it is possible that the
> function
> + // object and the allocator have the same type).
> + static_assert(!is_same<_T1, _T2>::value,
> + "__compressed_pair cannot be instantated when T1 and T2 are the same
> type; "
> + "The current implementation is NOT ABI-compatible with the previous "
> + "implementation for this configuration");
>
> -#endif // _LIBCPP_HAS_NO_VARIADICS
> -
> - _LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT
> {return *this;}
> - _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT
> {return *this;}
> -
> - _LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT
> {return *this;}
> - _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const
> _NOEXCEPT {return *this;}
> -
> - _LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {
> - }
> -};
> -
> -template <class _T1, class _T2>
> -class __compressed_pair
> - : private __libcpp_compressed_pair_imp<_T1, _T2>
> -{
> - typedef __libcpp_compressed_pair_imp<_T1, _T2> base;
> public:
> - typedef typename base::_T1_param _T1_param;
> - typedef typename base::_T2_param _T2_param;
> -
> - typedef typename base::_T1_reference _T1_reference;
> - typedef typename base::_T2_reference _T2_reference;
> -
> - typedef typename base::_T1_const_reference _T1_const_reference;
> - typedef typename base::_T2_const_reference _T2_const_reference;
> -
> - _LIBCPP_INLINE_VISIBILITY __compressed_pair() {}
> - _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1)
> - : base(_VSTD::forward<_T1_param>(__t1)) {}
> - _LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2)
> - : base(_VSTD::forward<_T2_param>(__t2)) {}
> - _LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param
> __t2)
> - : base(_VSTD::forward<_T1_param>(__t1),
> _VSTD::forward<_T2_param>(__t2)) {}
> +#ifndef _LIBCPP_CXX03_LANG
> + _LIBCPP_INLINE_VISIBILITY
> + __compressed_pair() = default;
>
> -#ifndef _LIBCPP_HAS_NO_VARIADICS
> + template <class _Tp, typename enable_if<!is_same<typename
> decay<_Tp>::type,
> +
> __compressed_pair>::value,
> + bool>::type = true>
> + _LIBCPP_INLINE_VISIBILITY constexpr explicit
> + __compressed_pair(_Tp&& __t)
> + : _Base1(std::forward<_Tp>(__t)), _Base2() {}
> +
> + template <class _Tp>
> + _LIBCPP_INLINE_VISIBILITY constexpr
> + __compressed_pair(__second_tag, _Tp&& __t)
> + : _Base1(), _Base2(std::forward<_Tp>(__t)) {}
> +
> + template <class _U1, class _U2>
> + _LIBCPP_INLINE_VISIBILITY constexpr
> + __compressed_pair(_U1&& __t1, _U2&& __t2)
> + : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2))
> {}
> +
> + template <class... _Args1, class... _Args2>
> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
> + __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...>
> __first_args,
> + tuple<_Args2...> __second_args)
> + : _Base1(__pc, _VSTD::move(__first_args),
> + typename __make_tuple_indices<sizeof...(_Args1)>::type()),
> + _Base2(__pc, _VSTD::move(__second_args),
> + typename __make_tuple_indices<sizeof...(_Args2)>::type())
> {}
>
> - template <class... _Args1, class... _Args2>
> - _LIBCPP_INLINE_VISIBILITY
> - __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...>
> __first_args,
> - tuple<_Args2...>
> __second_args)
> - : base(__pc, _VSTD::move(__first_args),
> _VSTD::move(__second_args),
> - typename __make_tuple_indices<sizeof...
> (_Args1)>::type(),
> - typename __make_tuple_indices<sizeof...(_Args2)
> >::type())
> - {}
> -
> -#endif // _LIBCPP_HAS_NO_VARIADICS
> +#else
> + _LIBCPP_INLINE_VISIBILITY
> + __compressed_pair() {}
>
> - _LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT
> {return base::first();}
> - _LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT
> {return base::first();}
> + _LIBCPP_INLINE_VISIBILITY explicit
> + __compressed_pair(_T1 __t1) : _Base1(_VSTD::forward<_T1>(__t1)) {}
>
> - _LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT
> {return base::second();}
> - _LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const
> _NOEXCEPT {return base::second();}
> + _LIBCPP_INLINE_VISIBILITY
> + __compressed_pair(__second_tag, _T2 __t2)
> + : _Base1(), _Base2(_VSTD::forward<_T2>(__t2)) {}
> +
> + _LIBCPP_INLINE_VISIBILITY
> + __compressed_pair(_T1 __t1, _T2 __t2)
> + : _Base1(_VSTD::forward<_T1>(__t1)), _Base2(_VSTD::forward<_T2>(__t2))
> {}
> +#endif
>
> - _LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {base::swap(__x);}
> + _LIBCPP_INLINE_VISIBILITY
> + typename _Base1::reference first() _NOEXCEPT {
> + return static_cast<_Base1&>(*this).__get();
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + typename _Base1::const_reference first() const _NOEXCEPT {
> + return static_cast<_Base1 const&>(*this).__get();
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + typename _Base2::reference second() _NOEXCEPT {
> + return static_cast<_Base2&>(*this).__get();
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + typename _Base2::const_reference second() const _NOEXCEPT {
> + return static_cast<_Base2 const&>(*this).__get();
> + }
> +
> + _LIBCPP_INLINE_VISIBILITY
> + void swap(__compressed_pair& __x)
> + _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> + __is_nothrow_swappable<_T2>::value)
> + {
> + using std::swap;
> + swap(first(), __x.first());
> + swap(second(), __x.second());
> + }
> };
>
> template <class _T1, class _T2>
> inline _LIBCPP_INLINE_VISIBILITY
> -void
> -swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
> - _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> - __is_nothrow_swappable<_T2>::value)
> - {__x.swap(__y);}
> +void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>&
> __y)
> + _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
> + __is_nothrow_swappable<_T2>::value) {
> + __x.swap(__y);
> +}
>
> // __same_or_less_cv_qualified
>
> @@ -2401,7 +2268,7 @@ struct __same_or_less_cv_qualified<_Ptr1
> template <class _Tp>
> struct _LIBCPP_TEMPLATE_VIS default_delete
> {
> -#ifndef _LIBCPP_CXX03_LANG
> +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete()
> _NOEXCEPT = default;
> #else
> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete()
> _NOEXCEPT {}
> @@ -2421,7 +2288,7 @@ template <class _Tp>
> struct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]>
> {
> public:
> -#ifndef _LIBCPP_CXX03_LANG
> +#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete()
> _NOEXCEPT = default;
> #else
> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR default_delete()
> _NOEXCEPT {}
>
> Modified: libcxx/trunk/include/string
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/
> string?rev=300140&r1=300139&r2=300140&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/include/string (original)
> +++ libcxx/trunk/include/string Wed Apr 12 18:45:53 2017
> @@ -1511,7 +1511,7 @@ basic_string<_CharT, _Traits, _Allocator
> #else
> _NOEXCEPT
> #endif
> -: __r_(__a)
> +: __r_(__second_tag(), __a)
> {
> #if _LIBCPP_DEBUG_LEVEL >= 2
> __get_db()->__insert_c(this);
> @@ -1582,7 +1582,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT*
> __s, const _Allocator& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator)
> detected nullptr");
> __init(__s, traits_type::length(__s));
> @@ -1605,7 +1605,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT*
> __s, size_type __n, const _Allocator& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*,
> n, allocator) detected nullptr");
> __init(__s, __n);
> @@ -1616,7 +1616,7 @@ basic_string<_CharT, _Traits, _Allocator
>
> template <class _CharT, class _Traits, class _Allocator>
> basic_string<_CharT, _Traits, _Allocator>::basic_string(const
> basic_string& __str)
> - : __r_(__alloc_traits::select_on_container_copy_
> construction(__str.__alloc()))
> + : __r_(__second_tag(), __alloc_traits::select_on_
> container_copy_construction(__str.__alloc()))
> {
> if (!__str.__is_long())
> __r_.first().__r = __str.__r_.first().__r;
> @@ -1630,7 +1630,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> basic_string<_CharT, _Traits, _Allocator>::basic_string(
> const basic_string& __str, const allocator_type& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> if (!__str.__is_long())
> __r_.first().__r = __str.__r_.first().__r;
> @@ -1664,7 +1664,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(basic_string&&
> __str, const allocator_type& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> if (__str.__is_long() && __a != __str.__alloc()) // copy, not move
> __init(_VSTD::__to_raw_pointer(__str.__get_long_pointer()),
> __str.__get_long_size());
> @@ -1719,7 +1719,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n,
> _CharT __c, const _Allocator& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> __init(__n, __c);
> #if _LIBCPP_DEBUG_LEVEL >= 2
> @@ -1731,7 +1731,7 @@ template <class _CharT, class _Traits, c
> basic_string<_CharT, _Traits, _Allocator>::basic_string(const
> basic_string& __str,
> size_type __pos,
> size_type __n,
> const _Allocator&
> __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> size_type __str_sz = __str.size();
> if (__pos > __str_sz)
> @@ -1746,7 +1746,7 @@ template <class _CharT, class _Traits, c
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(const
> basic_string& __str, size_type __pos,
> const _Allocator&
> __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> size_type __str_sz = __str.size();
> if (__pos > __str_sz)
> @@ -1762,7 +1762,7 @@ template <class _Tp>
> basic_string<_CharT, _Traits, _Allocator>::basic_string(
> const _Tp& __t, size_type __pos, size_type __n, const
> allocator_type& __a,
> typename enable_if<__can_be_converted_to_string_view<_CharT,
> _Traits, _Tp>::value, void>::type *)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> __self_view __sv = __self_view(__t).substr(__pos, __n);
> __init(__sv.data(), __sv.size());
> @@ -1784,7 +1784,7 @@ basic_string<_CharT, _Traits, _Allocator
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view
> __sv, const _Allocator& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> __init(__sv.data(), __sv.size());
> #if _LIBCPP_DEBUG_LEVEL >= 2
> @@ -1866,7 +1866,7 @@ template<class _InputIterator>
> inline _LIBCPP_INLINE_VISIBILITY
> basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator
> __first, _InputIterator __last,
> const
> allocator_type& __a)
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> __init(__first, __last);
> #if _LIBCPP_DEBUG_LEVEL >= 2
> @@ -1889,10 +1889,10 @@ basic_string<_CharT, _Traits, _Allocator
>
> template <class _CharT, class _Traits, class _Allocator>
> inline _LIBCPP_INLINE_VISIBILITY
> +
> basic_string<_CharT, _Traits, _Allocator>::basic_string(
> initializer_list<_CharT> __il, const _Allocator& __a)
> -
> - : __r_(__a)
> + : __r_(__second_tag(), __a)
> {
> __init(__il.begin(), __il.end());
> #if _LIBCPP_DEBUG_LEVEL >= 2
>
> Modified: libcxx/trunk/test/std/utilities/memory/unique.ptr/
> unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp
> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/
> utilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.
> runtime.ctor/default01.fail.cpp?rev=300140&r1=300139&r2=300140&view=diff
> ============================================================
> ==================
> --- libcxx/trunk/test/std/utilities/memory/unique.ptr/
> unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp (original)
> +++ libcxx/trunk/test/std/utilities/memory/unique.ptr/
> unique.ptr.runtime/unique.ptr.runtime.ctor/default01.fail.cpp Wed Apr 12
> 18:45:53 2017
> @@ -15,24 +15,25 @@
>
> // default unique_ptr ctor should require default Deleter ctor
>
> -
> #include <memory>
> +#include "test_macros.h"
>
> -class Deleter
> -{
> - // expected-error at memory:* {{base class 'Deleter' has private
> default constructor}}
> - // expected-note at memory:* + {{in instantiation of member function}}
> - Deleter() {} // expected-note {{implicitly declared private here}}
> +class Deleter {
> + Deleter() {}
>
> public:
> + Deleter(Deleter&) {}
> + Deleter& operator=(Deleter&) { return *this; }
>
> - Deleter(Deleter&) {}
> - Deleter& operator=(Deleter&) { return *this; }
> -
> - void operator()(void*) const {}
> + void operator()(void*) const {}
> };
>
> -int main()
> -{
> - std::unique_ptr<int[], Deleter> p;
> +int main() {
> +#if TEST_STD_VER >= 11
> + // expected-error at memory:* {{call to implicitly-deleted default
> constructor}}
> + // expected-note at memory:* {{implicitly deleted because base class
> 'Deleter' has an inaccessible default constructor}}
> +#else
> + // expected-error at memory:* {{base class 'Deleter' has private default
> constructor}}
> +#endif
> + std::unique_ptr<int[], Deleter> p; // expected-note {{requested here}}
> }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170424/82ab3914/attachment-0001.html>
More information about the cfe-commits
mailing list