diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -98,7 +98,15 @@ typedef _Tp __node_value_type; size_t __hash_; + +#ifndef _LIBCPP_CXX03_LANG + union { __node_value_type __value_; }; + + _LIBCPP_INLINE_VISIBILITY + explicit __hash_node() {} +#else __node_value_type __value_; +#endif }; inline _LIBCPP_INLINE_VISIBILITY @@ -2453,6 +2461,9 @@ "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)_VSTD::addressof(*__h)) __node(); +#endif __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); __h.get_deleter().__value_constructed = true; __h->__hash_ = hash_function()(__h->__value_); @@ -2470,6 +2481,9 @@ "Construct cannot be called with a hash value type"); __node_allocator& __na = __node_alloc(); __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)_VSTD::addressof(*__h)) __node(); +#endif __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_First>(__f), _VSTD::forward<_Rest>(__rest)...); diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -277,7 +277,14 @@ { typedef _Tp value_type; +#ifndef _LIBCPP_CXX03_LANG + union { value_type __value_; }; + + _LIBCPP_INLINE_VISIBILITY + explicit __forward_list_node() {} +#else value_type __value_; +#endif }; @@ -850,6 +857,14 @@ void reverse() _NOEXCEPT; private: + typedef __allocator_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; + + void __construct_empty_node(__node_holder &__h) { +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)_VSTD::addressof(*__h)) __node(); +#endif + } #ifndef _LIBCPP_CXX03_LANG void __move_assign(forward_list& __x, true_type) @@ -898,12 +913,12 @@ if (__n > 0) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); __h->__next_ = nullptr; __p->__next_ = __h.release(); @@ -920,12 +935,12 @@ if (__n > 0) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __p = base::__before_begin(); __n > 0; --__n, __p = __p->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); __h->__next_ = nullptr; __p->__next_ = __h.release(); @@ -1127,8 +1142,8 @@ forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); __h->__next_ = base::__before_begin()->__next_; @@ -1143,8 +1158,8 @@ forward_list<_Tp, _Alloc>::push_front(value_type&& __v) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); @@ -1157,8 +1172,8 @@ forward_list<_Tp, _Alloc>::push_front(const value_type& __v) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); __h->__next_ = base::__before_begin()->__next_; base::__before_begin()->__next_ = __h.release(); @@ -1184,8 +1199,8 @@ { __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::forward<_Args>(__args)...); __h->__next_ = __r->__next_; @@ -1199,8 +1214,8 @@ { __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), _VSTD::move(__v)); __h->__next_ = __r->__next_; __r->__next_ = __h.release(); @@ -1215,8 +1230,8 @@ { __begin_node_pointer const __r = __p.__get_begin(); __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); __h->__next_ = __r->__next_; __r->__next_ = __h.release(); @@ -1232,8 +1247,8 @@ if (__n > 0) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); __node_pointer __first = __h.release(); __node_pointer __last = __first; @@ -1244,6 +1259,7 @@ for (--__n; __n != 0; --__n, __last = __last->__next_) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); __last->__next_ = __h.release(); } @@ -1282,8 +1298,8 @@ if (__f != __l) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __node_holder __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); __node_pointer __first = __h.release(); __node_pointer __last = __first; @@ -1294,6 +1310,7 @@ for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); __last->__next_ = __h.release(); } @@ -1375,12 +1392,12 @@ if (__n > 0) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_)); __h->__next_ = nullptr; __ptr->__next_ = __h.release(); @@ -1407,12 +1424,12 @@ if (__n > 0) { __node_allocator& __a = base::__alloc(); - typedef __allocator_destructor<__node_allocator> _Dp; - unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); + unique_ptr<__node, _Dp> __h(nullptr, _Dp(__a, 1)); for (__begin_node_pointer __ptr = __p.__get_begin(); __n > 0; --__n, __ptr = __ptr->__next_as_begin()) { __h.reset(__node_traits::allocate(__a, 1)); + __construct_empty_node(__h); __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); __h->__next_ = nullptr; __ptr->__next_ = __h.release(); diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -270,11 +270,20 @@ struct __list_node : public __list_node_base<_Tp, _VoidPtr> { +#ifndef _LIBCPP_CXX03_LANG + union { _Tp __value_; }; +#else _Tp __value_; +#endif typedef __list_node_base<_Tp, _VoidPtr> __base; typedef typename __base::__link_pointer __link_pointer; +#ifndef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + explicit __list_node() {} +#endif + _LIBCPP_INLINE_VISIBILITY __link_pointer __as_link() { return static_cast<__link_pointer>(__base::__self()); @@ -1113,6 +1122,9 @@ _LIBCPP_INLINE_VISIBILITY __hold_pointer __allocate_node(__node_allocator& __na) { __node_pointer __p = __node_alloc_traits::allocate(__na, 1); +#ifndef _LIBCPP_CXX03_LANG + ::new ((void*)_VSTD::addressof(*__p)) __node(); +#endif __p->__prev_ = nullptr; return __hold_pointer(__p, __node_destructor(__na, 1)); }