Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e1f1cbf

Browse filesBrowse files
committed
[libc++] Avoid type-punning between __Value_type and pair
1 parent 6c9e098 commit e1f1cbf
Copy full SHA for e1f1cbf

File tree

Expand file treeCollapse file tree

6 files changed

+98
-139
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+98
-139
lines changed

‎libcxx/include/__fwd/pair.h

Copy file name to clipboardExpand all lines: libcxx/include/__fwd/pair.h
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2222
template <class, class>
2323
struct _LIBCPP_TEMPLATE_VIS pair;
2424

25+
template <class _Type>
26+
inline const bool __is_pair_v = false;
27+
28+
template <class _Type1, class _Type2>
29+
inline const bool __is_pair_v<pair<_Type1, _Type2> > = true;
30+
2531
template <size_t _Ip, class _T1, class _T2>
2632
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&
2733
get(pair<_T1, _T2>&) _NOEXCEPT;

‎libcxx/include/__memory/uses_allocator_construction.h

Copy file name to clipboardExpand all lines: libcxx/include/__memory/uses_allocator_construction.h
+1-8Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <__memory/uses_allocator.h>
1515
#include <__tuple/tuple_like_no_subrange.h>
1616
#include <__type_traits/enable_if.h>
17-
#include <__type_traits/is_same.h>
1817
#include <__type_traits/remove_cv.h>
1918
#include <__utility/declval.h>
2019
#include <__utility/pair.h>
@@ -31,14 +30,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
3130

3231
#if _LIBCPP_STD_VER >= 17
3332

34-
template <class _Type>
35-
inline constexpr bool __is_std_pair = false;
36-
37-
template <class _Type1, class _Type2>
38-
inline constexpr bool __is_std_pair<pair<_Type1, _Type2>> = true;
39-
4033
template <class _Tp>
41-
inline constexpr bool __is_cv_std_pair = __is_std_pair<remove_cv_t<_Tp>>;
34+
inline constexpr bool __is_cv_std_pair = __is_pair_v<remove_cv_t<_Tp>>;
4235

4336
template <class _Tp, class = void>
4437
struct __uses_allocator_construction_args;

‎libcxx/include/__node_handle

Copy file name to clipboardExpand all lines: libcxx/include/__node_handle
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,15 @@ struct __set_node_handle_specifics {
175175

176176
template <class _NodeType, class _Derived>
177177
struct __map_node_handle_specifics {
178-
typedef typename _NodeType::__node_value_type::key_type key_type;
179-
typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
178+
typedef __remove_const_t<typename _NodeType::__node_value_type::first_type> key_type;
179+
typedef typename _NodeType::__node_value_type::second_type mapped_type;
180180

181181
_LIBCPP_HIDE_FROM_ABI key_type& key() const {
182-
return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().first;
182+
return const_cast<key_type&>(static_cast<_Derived const*>(this)->__ptr_->__get_value().first);
183183
}
184184

185185
_LIBCPP_HIDE_FROM_ABI mapped_type& mapped() const {
186-
return static_cast<_Derived const*>(this)->__ptr_->__get_value().__ref().second;
186+
return static_cast<_Derived const*>(this)->__ptr_->__get_value().second;
187187
}
188188
};
189189

‎libcxx/include/__tree

Copy file name to clipboardExpand all lines: libcxx/include/__tree
+61-41Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -505,48 +505,24 @@ struct __is_tree_value_type<_One> : __is_tree_value_type_imp<__remove_cvref_t<_O
505505
template <class _Tp>
506506
struct __tree_key_value_types {
507507
typedef _Tp key_type;
508-
typedef _Tp __node_value_type;
509508
typedef _Tp __container_value_type;
510509
static const bool __is_map = false;
511510

512511
_LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; }
513-
_LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; }
514-
_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); }
515-
_LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); }
516512
};
517513

518514
template <class _Key, class _Tp>
519515
struct __tree_key_value_types<__value_type<_Key, _Tp> > {
520516
typedef _Key key_type;
521517
typedef _Tp mapped_type;
522-
typedef __value_type<_Key, _Tp> __node_value_type;
523518
typedef pair<const _Key, _Tp> __container_value_type;
524519
typedef __container_value_type __map_value_type;
525520
static const bool __is_map = true;
526521

527-
_LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__node_value_type const& __t) {
528-
return __t.__get_value().first;
529-
}
530-
531522
template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
532523
_LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Up& __t) {
533524
return __t.first;
534525
}
535-
536-
_LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __t) {
537-
return __t.__get_value();
538-
}
539-
540-
template <class _Up, __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, int> = 0>
541-
_LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) {
542-
return __t;
543-
}
544-
545-
_LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) {
546-
return std::addressof(__n.__get_value());
547-
}
548-
549-
_LIBCPP_HIDE_FROM_ABI static pair<key_type&&, mapped_type&&> __move(__node_value_type& __v) { return __v.__move(); }
550526
};
551527

552528
template <class _VoidPtr>
@@ -587,6 +563,19 @@ struct __tree_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> {
587563
typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer;
588564
};
589565

566+
template <class _Tp>
567+
struct __get_node_value_type {
568+
using type _LIBCPP_NODEBUG = _Tp;
569+
};
570+
571+
template <class _Key, class _ValueT>
572+
struct __get_node_value_type<__value_type<_Key, _ValueT> > {
573+
using type _LIBCPP_NODEBUG = pair<const _Key, _ValueT>;
574+
};
575+
576+
template <class _Tp>
577+
using __get_node_value_type_t = typename __get_node_value_type<_Tp>::type;
578+
590579
template <class _NodePtr, class _NodeT = typename pointer_traits<_NodePtr>::element_type>
591580
struct __tree_node_types;
592581

@@ -601,7 +590,7 @@ public:
601590
typedef typename pointer_traits<_NodePtr>::element_type __node_type;
602591
typedef _NodePtr __node_pointer;
603592

604-
typedef _Tp __node_value_type;
593+
using __node_value_type = __get_node_value_type_t<_Tp>;
605594
typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer;
606595
typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer;
607596
typedef typename __base::__end_node_pointer __iter_pointer;
@@ -653,11 +642,11 @@ public:
653642
template <class _Tp, class _VoidPtr>
654643
class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
655644
public:
656-
typedef _Tp __node_value_type;
645+
using __node_value_type = __get_node_value_type_t<_Tp>;
657646

658647
__node_value_type __value_;
659648

660-
_LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; }
649+
_LIBCPP_HIDE_FROM_ABI __node_value_type& __get_value() { return __value_; }
661650

662651
~__tree_node() = delete;
663652
__tree_node(__tree_node const&) = delete;
@@ -688,7 +677,7 @@ public:
688677

689678
_LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {
690679
if (__value_constructed)
691-
__alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_));
680+
__alloc_traits::destroy(__na_, std::addressof(__p->__value_));
692681
if (__p)
693682
__alloc_traits::deallocate(__na_, __p, 1);
694683
}
@@ -719,7 +708,7 @@ class _LIBCPP_TEMPLATE_VIS __tree_iterator {
719708

720709
public:
721710
typedef bidirectional_iterator_tag iterator_category;
722-
typedef _Tp value_type;
711+
using value_type = __get_node_value_type_t<_Tp>;
723712
typedef _DiffType difference_type;
724713
typedef value_type& reference;
725714
typedef typename _NodeTypes::__node_value_type_pointer pointer;
@@ -796,7 +785,7 @@ class _LIBCPP_TEMPLATE_VIS __tree_const_iterator {
796785

797786
public:
798787
typedef bidirectional_iterator_tag iterator_category;
799-
typedef _Tp value_type;
788+
using value_type = __get_node_value_type_t<_Tp>;
800789
typedef _DiffType difference_type;
801790
typedef const value_type& reference;
802791
typedef typename _NodeTypes::__const_node_value_type_pointer pointer;
@@ -809,7 +798,7 @@ public:
809798
}
810799

811800
private:
812-
typedef __tree_iterator<value_type, __node_pointer, difference_type> __non_const_iterator;
801+
typedef __tree_iterator<_Tp, __node_pointer, difference_type> __non_const_iterator;
813802

814803
public:
815804
_LIBCPP_HIDE_FROM_ABI __tree_const_iterator(__non_const_iterator __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
@@ -1276,6 +1265,32 @@ private:
12761265
}
12771266
_LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__tree&, false_type) _NOEXCEPT {}
12781267

1268+
template <class _From, __enable_if_t<__is_pair_v<__remove_cvref_t<_From> >, int> = 0>
1269+
_LIBCPP_HIDE_FROM_ABI static void __assign_value(__get_node_value_type_t<value_type>& __lhs, _From&& __rhs) {
1270+
using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1271+
1272+
reinterpret_cast<__punned_type&>(__lhs) = reinterpret_cast<__copy_cvref_t<_From, __punned_type>&&>(__rhs);
1273+
}
1274+
1275+
template <class _To,
1276+
class _From,
1277+
class _ValueT = _Tp,
1278+
__enable_if_t<__is_tree_value_type<_ValueT>::value && !__is_pair_v<__remove_cvref_t<_From> >, int> = 0>
1279+
_LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) {
1280+
static_assert(__is_pair_v<__remove_cvref_t<_From> >);
1281+
using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1282+
1283+
reinterpret_cast<__punned_type&>(__lhs) = __rhs;
1284+
}
1285+
1286+
template <class _To,
1287+
class _From,
1288+
class _ValueT = _Tp,
1289+
__enable_if_t<!__is_tree_value_type<_ValueT>::value && !__is_pair_v<__remove_cvref_t<_From> >, int> = 0>
1290+
_LIBCPP_HIDE_FROM_ABI static void __assign_value(_To& __lhs, _From&& __rhs) {
1291+
__lhs = std::forward<_From>(__rhs);
1292+
}
1293+
12791294
struct _DetachedTreeCache {
12801295
_LIBCPP_HIDE_FROM_ABI explicit _DetachedTreeCache(__tree* __t) _NOEXCEPT
12811296
: __t_(__t),
@@ -1416,13 +1431,13 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
14161431
if (size() != 0) {
14171432
_DetachedTreeCache __cache(this);
14181433
for (; __cache.__get() && __first != __last; ++__first) {
1419-
__cache.__get()->__value_ = *__first;
1434+
__assign_value(__cache.__get()->__value_, *__first);
14201435
__node_insert_multi(__cache.__get());
14211436
__cache.__advance();
14221437
}
14231438
}
14241439
for (; __first != __last; ++__first)
1425-
__insert_multi(_NodeTypes::__get_value(*__first));
1440+
__insert_multi(*__first);
14261441
}
14271442

14281443
template <class _Tp, class _Compare, class _Allocator>
@@ -1501,13 +1516,19 @@ void __tree<_Tp, _Compare, _Allocator>::__move_assign(__tree& __t, false_type) {
15011516
if (size() != 0) {
15021517
_DetachedTreeCache __cache(this);
15031518
while (__cache.__get() != nullptr && __t.size() != 0) {
1504-
__cache.__get()->__value_ = std::move(__t.remove(__t.begin())->__value_);
1519+
__assign_value(__cache.__get()->__value_, std::move(__t.remove(__t.begin())->__value_));
15051520
__node_insert_multi(__cache.__get());
15061521
__cache.__advance();
15071522
}
15081523
}
1509-
while (__t.size() != 0)
1510-
__insert_multi(__e, _NodeTypes::__move(__t.remove(__t.begin())->__value_));
1524+
while (__t.size() != 0) {
1525+
if constexpr (__is_tree_value_type<_Tp>::value) {
1526+
using __punned_type = pair<typename _NodeTypes::key_type, typename _NodeTypes::mapped_type>;
1527+
__insert_multi(__e, reinterpret_cast<__punned_type&&>(__t.remove(__t.begin())->__value_));
1528+
} else {
1529+
__insert_multi(__e, std::move(__t.remove(__t.begin())->__value_));
1530+
}
1531+
}
15111532
}
15121533
}
15131534

@@ -1533,7 +1554,7 @@ void __tree<_Tp, _Compare, _Allocator>::destroy(__node_pointer __nd) _NOEXCEPT {
15331554
destroy(static_cast<__node_pointer>(__nd->__left_));
15341555
destroy(static_cast<__node_pointer>(__nd->__right_));
15351556
__node_allocator& __na = __node_alloc();
1536-
__node_traits::destroy(__na, _NodeTypes::__get_ptr(__nd->__value_));
1557+
__node_traits::destroy(__na, std::addressof(__nd->__value_));
15371558
__node_traits::deallocate(__na, __nd, 1);
15381559
}
15391560
}
@@ -1803,10 +1824,9 @@ template <class _Tp, class _Compare, class _Allocator>
18031824
template <class... _Args>
18041825
typename __tree<_Tp, _Compare, _Allocator>::__node_holder
18051826
__tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&&... __args) {
1806-
static_assert(!__is_tree_value_type<_Args...>::value, "Cannot construct from __value_type");
18071827
__node_allocator& __na = __node_alloc();
18081828
__node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
1809-
__node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), std::forward<_Args>(__args)...);
1829+
__node_traits::construct(__na, std::addressof(__h->__value_), std::forward<_Args>(__args)...);
18101830
__h.get_deleter().__value_constructed = true;
18111831
return __h;
18121832
}
@@ -1874,7 +1894,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const __container_value_
18741894
__node_pointer __r = static_cast<__node_pointer>(__child);
18751895
bool __inserted = false;
18761896
if (__child == nullptr) {
1877-
__nd->__value_ = __v;
1897+
__assign_value(__nd->__value_, __v);
18781898
__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));
18791899
__r = __nd;
18801900
__inserted = true;
@@ -2036,7 +2056,7 @@ typename __tree<_Tp, _Compare, _Allocator>::iterator __tree<_Tp, _Compare, _Allo
20362056
__node_pointer __np = __p.__get_np();
20372057
iterator __r = __remove_node_pointer(__np);
20382058
__node_allocator& __na = __node_alloc();
2039-
__node_traits::destroy(__na, _NodeTypes::__get_ptr(const_cast<__node_value_type&>(*__p)));
2059+
__node_traits::destroy(__na, std::addressof(const_cast<__node_value_type&>(*__p)));
20402060
__node_traits::deallocate(__na, __np, 1);
20412061
return __r;
20422062
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.