This broke a bunch of bots. Fix incoming. Please don't revert. On Wed, Apr 12, 2017 at 5:45 PM, Eric Fiselier via cfe-commits < cfe-commits@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@memory:* {{base class 'Deleter' has private > default constructor}} > - // expected-note@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@memory:* {{call to implicitly-deleted default > constructor}} > + // expected-note@memory:* {{implicitly deleted because base class > 'Deleter' has an inaccessible default constructor}} > +#else > + // expected-error@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits