Skip to content

Commit 1ba8ed0

Browse files
philnik777ldionne
andauthored
[libc++] Mark more types as trivially relocatable (#89724)
Co-authored-by: Louis Dionne <[email protected]>
1 parent f84056c commit 1ba8ed0

File tree

21 files changed

+202
-0
lines changed

21 files changed

+202
-0
lines changed

libcxx/docs/ReleaseNotes/19.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Improvements and New Features
5858
-----------------------------
5959

6060
- The performance of growing ``std::vector`` has been improved for trivially relocatable types.
61+
- A lot of types are considered trivially relocatable now, including ``vector`` and ``string``.
6162
- The performance of ``ranges::fill`` and ``ranges::fill_n`` has been improved for ``vector<bool>::iterator``\s,
6263
resulting in a performance increase of up to 1400x.
6364
- The ``std::mismatch`` algorithm has been optimized for integral types, which can lead up to 40x performance

libcxx/include/__exception/exception_ptr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
6666
friend _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT;
6767

6868
public:
69+
// exception_ptr is basically a COW string.
70+
using __trivially_relocatable = exception_ptr;
71+
6972
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
7073
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
7174

libcxx/include/__expected/expected.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <__type_traits/is_swappable.h>
3232
#include <__type_traits/is_trivially_constructible.h>
3333
#include <__type_traits/is_trivially_destructible.h>
34+
#include <__type_traits/is_trivially_relocatable.h>
3435
#include <__type_traits/is_void.h>
3536
#include <__type_traits/lazy.h>
3637
#include <__type_traits/negation.h>
@@ -463,6 +464,11 @@ class expected : private __expected_base<_Tp, _Err> {
463464
using error_type = _Err;
464465
using unexpected_type = unexpected<_Err>;
465466

467+
using __trivially_relocatable =
468+
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value,
469+
expected,
470+
void>;
471+
466472
template <class _Up>
467473
using rebind = expected<_Up, error_type>;
468474

libcxx/include/__locale

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
4949

5050
class _LIBCPP_EXPORTED_FROM_ABI locale {
5151
public:
52+
// locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor.
53+
using __trivially_relocatable = locale;
54+
5255
// types:
5356
class _LIBCPP_EXPORTED_FROM_ABI facet;
5457
class _LIBCPP_EXPORTED_FROM_ABI id;

libcxx/include/__memory/shared_ptr.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr {
419419
typedef _Tp element_type;
420420
#endif
421421

422+
// A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
423+
// any bookkeeping, so it's always trivially relocatable.
424+
using __trivially_relocatable = shared_ptr;
425+
422426
private:
423427
element_type* __ptr_;
424428
__shared_weak_count* __cntrl_;
@@ -1301,6 +1305,10 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr {
13011305
typedef _Tp element_type;
13021306
#endif
13031307

1308+
// A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1309+
// any bookkeeping, so it's always trivially relocatable.
1310+
using __trivially_relocatable = weak_ptr;
1311+
13041312
private:
13051313
element_type* __ptr_;
13061314
__shared_weak_count* __cntrl_;

libcxx/include/__split_buffer

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
#include <__memory/pointer_traits.h>
2525
#include <__memory/swap_allocator.h>
2626
#include <__type_traits/add_lvalue_reference.h>
27+
#include <__type_traits/conditional.h>
2728
#include <__type_traits/enable_if.h>
2829
#include <__type_traits/integral_constant.h>
2930
#include <__type_traits/is_nothrow_assignable.h>
3031
#include <__type_traits/is_nothrow_constructible.h>
3132
#include <__type_traits/is_swappable.h>
3233
#include <__type_traits/is_trivially_destructible.h>
34+
#include <__type_traits/is_trivially_relocatable.h>
3335
#include <__type_traits/remove_reference.h>
3436
#include <__utility/forward.h>
3537
#include <__utility/move.h>
@@ -64,6 +66,15 @@ public:
6466
using iterator = pointer;
6567
using const_iterator = const_pointer;
6668

69+
// A __split_buffer contains the following members which may be trivially relocatable:
70+
// - pointer: may be trivially relocatable, so it's checked
71+
// - allocator_type: may be trivially relocatable, so it's checked
72+
// __split_buffer doesn't have any self-references, so it's trivially relocatable if its members are.
73+
using __trivially_relocatable = __conditional_t<
74+
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
75+
__split_buffer,
76+
void>;
77+
6778
pointer __first_;
6879
pointer __begin_;
6980
pointer __end_;

libcxx/include/__utility/pair.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <__type_traits/is_nothrow_constructible.h>
3535
#include <__type_traits/is_same.h>
3636
#include <__type_traits/is_swappable.h>
37+
#include <__type_traits/is_trivially_relocatable.h>
3738
#include <__type_traits/nat.h>
3839
#include <__type_traits/remove_cvref.h>
3940
#include <__type_traits/unwrap_ref.h>
@@ -71,6 +72,11 @@ struct _LIBCPP_TEMPLATE_VIS pair
7172
_T1 first;
7273
_T2 second;
7374

75+
using __trivially_relocatable =
76+
__conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
77+
pair,
78+
void>;
79+
7480
_LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
7581
_LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
7682

libcxx/include/array

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
130130
#include <__type_traits/is_nothrow_constructible.h>
131131
#include <__type_traits/is_same.h>
132132
#include <__type_traits/is_swappable.h>
133+
#include <__type_traits/is_trivially_relocatable.h>
133134
#include <__type_traits/remove_cv.h>
134135
#include <__utility/empty.h>
135136
#include <__utility/integer_sequence.h>
@@ -166,6 +167,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
166167

167168
template <class _Tp, size_t _Size>
168169
struct _LIBCPP_TEMPLATE_VIS array {
170+
using __trivially_relocatable = __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>;
171+
169172
// types:
170173
using __self = array;
171174
using value_type = _Tp;

libcxx/include/deque

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,16 @@ public:
477477
using reverse_iterator = std::reverse_iterator<iterator>;
478478
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
479479

480+
// A deque contains the following members which may be trivially relocatable:
481+
// - __map: is a `__split_buffer`, see `__split_buffer` for more information on when it is trivially relocatable
482+
// - size_type: is always trivially relocatable, since it is required to be an integral type
483+
// - allocator_type: may not be trivially relocatable, so it's checked
484+
// None of these are referencing the `deque` itself, so if all of them are trivially relocatable, `deque` is too.
485+
using __trivially_relocatable = __conditional_t<
486+
__libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
487+
deque,
488+
void>;
489+
480490
static_assert(is_same<allocator_type, __rebind_alloc<__alloc_traits, value_type> >::value,
481491
"[allocator.requirements] states that rebinding an allocator to the same type should result in the "
482492
"original allocator");

libcxx/include/optional

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ namespace std {
209209
#include <__type_traits/is_trivially_assignable.h>
210210
#include <__type_traits/is_trivially_constructible.h>
211211
#include <__type_traits/is_trivially_destructible.h>
212+
#include <__type_traits/is_trivially_relocatable.h>
212213
#include <__type_traits/negation.h>
213214
#include <__type_traits/remove_const.h>
214215
#include <__type_traits/remove_cvref.h>
@@ -580,6 +581,8 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES optional
580581
public:
581582
using value_type = _Tp;
582583

584+
using __trivially_relocatable = conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
585+
583586
private:
584587
// Disable the reference extension using this static assert.
585588
static_assert(!is_same_v<__remove_cvref_t<value_type>, in_place_t>,

libcxx/include/tuple

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ template <class... Types>
240240
#include <__type_traits/is_reference.h>
241241
#include <__type_traits/is_same.h>
242242
#include <__type_traits/is_swappable.h>
243+
#include <__type_traits/is_trivially_relocatable.h>
243244
#include <__type_traits/lazy.h>
244245
#include <__type_traits/maybe_const.h>
245246
#include <__type_traits/nat.h>
@@ -537,6 +538,8 @@ class _LIBCPP_TEMPLATE_VIS tuple {
537538
get(const tuple<_Up...>&&) _NOEXCEPT;
538539

539540
public:
541+
using __trivially_relocatable = __conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>;
542+
540543
// [tuple.cnstr]
541544

542545
// tuple() constructors (including allocator_arg_t variants)

libcxx/include/variant

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ namespace std {
241241
#include <__type_traits/is_trivially_assignable.h>
242242
#include <__type_traits/is_trivially_constructible.h>
243243
#include <__type_traits/is_trivially_destructible.h>
244+
#include <__type_traits/is_trivially_relocatable.h>
244245
#include <__type_traits/is_void.h>
245246
#include <__type_traits/remove_const.h>
246247
#include <__type_traits/remove_cvref.h>
@@ -1180,6 +1181,9 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant
11801181
using __first_type = variant_alternative_t<0, variant>;
11811182

11821183
public:
1184+
using __trivially_relocatable =
1185+
conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
1186+
11831187
template <bool _Dummy = true,
11841188
enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
11851189
_LIBCPP_HIDE_FROM_ABI constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>)

libcxx/include/vector

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,15 @@ public:
406406
typedef std::reverse_iterator<iterator> reverse_iterator;
407407
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
408408

409+
// A vector containers the following members which may be trivially relocatable:
410+
// - pointer: may be trivially relocatable, so it's checked
411+
// - allocator_type: may be trivially relocatable, so it's checked
412+
// vector doesn't contain any self-references, so it's trivially relocatable if its members are.
413+
using __trivially_relocatable = __conditional_t<
414+
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
415+
vector,
416+
void>;
417+
409418
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
410419
"Allocator::value_type must be same type as value_type");
411420

libcxx/test/libcxx/transitive_includes/cxx03.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@ thread type_traits
903903
thread version
904904
tuple compare
905905
tuple cstddef
906+
tuple cstdint
906907
tuple exception
907908
tuple iosfwd
908909
tuple new

libcxx/test/libcxx/transitive_includes/cxx11.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ thread type_traits
910910
thread version
911911
tuple compare
912912
tuple cstddef
913+
tuple cstdint
913914
tuple exception
914915
tuple iosfwd
915916
tuple new

libcxx/test/libcxx/transitive_includes/cxx14.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ thread type_traits
913913
thread version
914914
tuple compare
915915
tuple cstddef
916+
tuple cstdint
916917
tuple exception
917918
tuple iosfwd
918919
tuple new

libcxx/test/libcxx/transitive_includes/cxx17.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ thread type_traits
914914
thread version
915915
tuple compare
916916
tuple cstddef
917+
tuple cstdint
917918
tuple exception
918919
tuple iosfwd
919920
tuple new

libcxx/test/libcxx/transitive_includes/cxx20.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ thread type_traits
920920
thread version
921921
tuple compare
922922
tuple cstddef
923+
tuple cstdint
923924
tuple exception
924925
tuple iosfwd
925926
tuple new

libcxx/test/libcxx/transitive_includes/cxx23.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ exception typeinfo
151151
exception version
152152
execution version
153153
expected cstddef
154+
expected cstdint
154155
expected initializer_list
155156
expected new
156157
expected version
@@ -484,6 +485,7 @@ regex typeinfo
484485
regex vector
485486
regex version
486487
scoped_allocator cstddef
488+
scoped_allocator cstdint
487489
scoped_allocator limits
488490
scoped_allocator new
489491
scoped_allocator tuple
@@ -640,6 +642,7 @@ thread typeinfo
640642
thread version
641643
tuple compare
642644
tuple cstddef
645+
tuple cstdint
643646
tuple version
644647
type_traits cstddef
645648
type_traits cstdint
@@ -674,6 +677,7 @@ unordered_set tuple
674677
unordered_set version
675678
utility compare
676679
utility cstddef
680+
utility cstdint
677681
utility initializer_list
678682
utility limits
679683
utility version

libcxx/test/libcxx/transitive_includes/cxx26.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ exception typeinfo
151151
exception version
152152
execution version
153153
expected cstddef
154+
expected cstdint
154155
expected initializer_list
155156
expected new
156157
expected version
@@ -484,6 +485,7 @@ regex typeinfo
484485
regex vector
485486
regex version
486487
scoped_allocator cstddef
488+
scoped_allocator cstdint
487489
scoped_allocator limits
488490
scoped_allocator new
489491
scoped_allocator tuple
@@ -640,6 +642,7 @@ thread typeinfo
640642
thread version
641643
tuple compare
642644
tuple cstddef
645+
tuple cstdint
643646
tuple version
644647
type_traits cstddef
645648
type_traits cstdint
@@ -674,6 +677,7 @@ unordered_set tuple
674677
unordered_set version
675678
utility compare
676679
utility cstddef
680+
utility cstdint
677681
utility initializer_list
678682
utility limits
679683
utility version

0 commit comments

Comments
 (0)