Skip to content

Commit 1df78ab

Browse files
committed
Example conversion for deque, using [[trivially_relocatable]].
1 parent 0533994 commit 1df78ab

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

include/__config

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,14 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
12811281
#define _LIBCPP_HAS_NO_IS_AGGREGATE
12821282
#endif
12831283

1284+
#ifndef _LIBCPP_TRIVIALLY_RELOCATABLE
1285+
#if __has_extension(trivially_relocatable)
1286+
#define _LIBCPP_TRIVIALLY_RELOCATABLE [[clang::trivially_relocatable]]
1287+
#else
1288+
#define _LIBCPP_TRIVIALLY_RELOCATABLE
1289+
#endif
1290+
#endif
1291+
12841292
#if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L
12851293
#define _LIBCPP_HAS_NO_COROUTINES
12861294
#endif

include/deque

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,13 @@ protected:
952952
typedef __deque_iterator<value_type, const_pointer, const_reference, __map_const_pointer,
953953
difference_type> const_iterator;
954954

955+
public:
956+
typedef integral_constant<bool,
957+
is_trivially_relocatable<pointer>::value &&
958+
is_trivially_relocatable<__pointer_allocator>::value &&
959+
is_trivially_relocatable<size_type>::value &&
960+
is_trivially_relocatable<allocator_type>::value
961+
> __allow_trivial_relocation;
955962
protected:
956963
__map __map_;
957964
size_type __start_;
@@ -1190,9 +1197,43 @@ __deque_base<_Tp, _Allocator>::clear() _NOEXCEPT
11901197
}
11911198
}
11921199

1200+
template <class _Tp, class _Allocator, bool = __deque_base<_Tp, _Allocator>::__allow_trivial_relocation::value>
1201+
class _LIBCPP_TEMPLATE_VIS __deque_relocate_base
1202+
: protected __deque_base<_Tp, _Allocator>
1203+
{
1204+
protected:
1205+
#ifndef _LIBCPP_CXX03_LANG
1206+
using __deque_base<_Tp, _Allocator>::__deque_base;
1207+
#else
1208+
_LIBCPP_INLINE_VISIBILITY
1209+
__deque_relocate_base() = default;
1210+
1211+
_LIBCPP_INLINE_VISIBILITY
1212+
__deque_relocate_base(const _Allocator& __a)
1213+
: __deque_base<_Tp, _Allocator>(__a) {}
1214+
#endif // _LIBCPP_CXX03_LANG
1215+
};
1216+
1217+
template <class _Tp, class _Allocator>
1218+
class _LIBCPP_TEMPLATE_VIS _LIBCPP_TRIVIALLY_RELOCATABLE __deque_relocate_base<_Tp, _Allocator, true>
1219+
: protected __deque_base<_Tp, _Allocator>
1220+
{
1221+
protected:
1222+
#ifndef _LIBCPP_CXX03_LANG
1223+
using __deque_base<_Tp, _Allocator>::__deque_base;
1224+
#else
1225+
_LIBCPP_INLINE_VISIBILITY
1226+
__deque_relocate_base() = default;
1227+
1228+
_LIBCPP_INLINE_VISIBILITY
1229+
__deque_relocate_base(const _Allocator& __a)
1230+
: __deque_base<_Tp, _Allocator>(__a) {}
1231+
#endif // _LIBCPP_CXX03_LANG
1232+
};
1233+
11931234
template <class _Tp, class _Allocator /*= allocator<_Tp>*/>
11941235
class _LIBCPP_TEMPLATE_VIS deque
1195-
: private __deque_base<_Tp, _Allocator>
1236+
: private __deque_relocate_base<_Tp, _Allocator>
11961237
{
11971238
public:
11981239
// types:
@@ -1203,6 +1244,7 @@ public:
12031244
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
12041245
"Allocator::value_type must be same type as value_type");
12051246

1247+
typedef __deque_relocate_base<value_type, allocator_type> __relocate_base;
12061248
typedef __deque_base<value_type, allocator_type> __base;
12071249

12081250
typedef typename __base::__alloc_traits __alloc_traits;
@@ -1223,7 +1265,7 @@ public:
12231265
deque()
12241266
_NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
12251267
{}
1226-
_LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __base(__a) {}
1268+
_LIBCPP_INLINE_VISIBILITY explicit deque(const allocator_type& __a) : __relocate_base(__a) {}
12271269
explicit deque(size_type __n);
12281270
#if _LIBCPP_STD_VER > 11
12291271
explicit deque(size_type __n, const _Allocator& __a);
@@ -1249,7 +1291,7 @@ public:
12491291
deque& operator=(initializer_list<value_type> __il) {assign(__il); return *this;}
12501292

12511293
_LIBCPP_INLINE_VISIBILITY
1252-
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
1294+
deque(deque&& __c) = default;
12531295
_LIBCPP_INLINE_VISIBILITY
12541296
deque(deque&& __c, const allocator_type& __a);
12551297
_LIBCPP_INLINE_VISIBILITY
@@ -1495,7 +1537,7 @@ deque<_Tp, _Allocator>::deque(size_type __n)
14951537
#if _LIBCPP_STD_VER > 11
14961538
template <class _Tp, class _Allocator>
14971539
deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a)
1498-
: __base(__a)
1540+
: __relocate_base(__a)
14991541
{
15001542
if (__n > 0)
15011543
__append(__n);
@@ -1511,7 +1553,7 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
15111553

15121554
template <class _Tp, class _Allocator>
15131555
deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
1514-
: __base(__a)
1556+
: __relocate_base(__a)
15151557
{
15161558
if (__n > 0)
15171559
__append(__n, __v);
@@ -1529,21 +1571,21 @@ template <class _Tp, class _Allocator>
15291571
template <class _InputIter>
15301572
deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a,
15311573
typename enable_if<__is_input_iterator<_InputIter>::value>::type*)
1532-
: __base(__a)
1574+
: __relocate_base(__a)
15331575
{
15341576
__append(__f, __l);
15351577
}
15361578

15371579
template <class _Tp, class _Allocator>
15381580
deque<_Tp, _Allocator>::deque(const deque& __c)
1539-
: __base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
1581+
: __relocate_base(__alloc_traits::select_on_container_copy_construction(__c.__alloc()))
15401582
{
15411583
__append(__c.begin(), __c.end());
15421584
}
15431585

15441586
template <class _Tp, class _Allocator>
15451587
deque<_Tp, _Allocator>::deque(const deque& __c, const allocator_type& __a)
1546-
: __base(__a)
1588+
: __relocate_base(__a)
15471589
{
15481590
__append(__c.begin(), __c.end());
15491591
}
@@ -1570,23 +1612,15 @@ deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il)
15701612

15711613
template <class _Tp, class _Allocator>
15721614
deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a)
1573-
: __base(__a)
1615+
: __relocate_base(__a)
15741616
{
15751617
__append(__il.begin(), __il.end());
15761618
}
15771619

1578-
template <class _Tp, class _Allocator>
1579-
inline
1580-
deque<_Tp, _Allocator>::deque(deque&& __c)
1581-
_NOEXCEPT_(is_nothrow_move_constructible<__base>::value)
1582-
: __base(_VSTD::move(__c))
1583-
{
1584-
}
1585-
15861620
template <class _Tp, class _Allocator>
15871621
inline
15881622
deque<_Tp, _Allocator>::deque(deque&& __c, const allocator_type& __a)
1589-
: __base(_VSTD::move(__c), __a)
1623+
: __relocate_base(_VSTD::move(__c), __a)
15901624
{
15911625
if (__a != __c.__alloc())
15921626
{

0 commit comments

Comments
 (0)