[libcxx] r300140 - [libcxx] Fix __compressed_pair so it doesn't copy the argument multiple times, and add constexpr.

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 24 16:01:12 PDT 2017


There is no easy way to change their names back. The same class is used to
store the first and second element, both have the name `__value_` now.

Sorry

/Eric

On Mon, Apr 24, 2017 at 4:02 PM, Lang Hames <lhames at gmail.com> wrote:

> 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/mem
>> ory?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>(_VS
>> TD::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>(_VS
>> TD::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>(_VS
>> TD::get<_I1>(__first_args))...),
>> -              _T2(_VSTD::forward<_Args2>(_VS
>> TD::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/str
>> ing?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_cont
>> ainer_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/ut
>> ilities/memory/unique.ptr/unique.ptr.runtime/unique.ptr.runt
>> ime.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/d4dbd16f/attachment-0001.html>


More information about the cfe-commits mailing list