Skip to content

Commit 1f48a11

Browse files
committed
[libc++] Mark more types as trivially relocatable
1 parent bfa8b64 commit 1f48a11

File tree

21 files changed

+200
-0
lines changed

21 files changed

+200
-0
lines changed

libcxx/docs/ReleaseNotes/19.rst

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

6161
- The performance of growing ``std::vector`` has been improved for trivially relocatable types.
62+
- A lot of types are considered trivially relocatable now, including ``vector`` and ``string``.
6263
- The performance of ``ranges::fill`` and ``ranges::fill_n`` has been improved for ``vector<bool>::iterator``\s,
6364
resulting in a performance increase of up to 1400x.
6465
- 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
@@ -422,6 +422,10 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr {
422422
typedef _Tp element_type;
423423
#endif
424424

425+
// A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
426+
// any bookkeeping, so it's always trivially relocatable.
427+
using __trivially_relocatable = shared_ptr;
428+
425429
private:
426430
element_type* __ptr_;
427431
__shared_weak_count* __cntrl_;
@@ -1304,6 +1308,10 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr {
13041308
typedef _Tp element_type;
13051309
#endif
13061310

1311+
// A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1312+
// any bookkeeping, so it's always trivially relocatable.
1313+
using __trivially_relocatable = weak_ptr;
1314+
13071315
private:
13081316
element_type* __ptr_;
13091317
__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
@@ -906,6 +906,7 @@ thread type_traits
906906
thread version
907907
tuple compare
908908
tuple cstddef
909+
tuple cstdint
909910
tuple exception
910911
tuple iosfwd
911912
tuple new

libcxx/test/libcxx/transitive_includes/cxx11.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/cxx14.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,7 @@ thread type_traits
916916
thread version
917917
tuple compare
918918
tuple cstddef
919+
tuple cstdint
919920
tuple exception
920921
tuple iosfwd
921922
tuple new

libcxx/test/libcxx/transitive_includes/cxx17.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,7 @@ thread type_traits
916916
thread version
917917
tuple compare
918918
tuple cstddef
919+
tuple cstdint
919920
tuple exception
920921
tuple iosfwd
921922
tuple new

libcxx/test/libcxx/transitive_includes/cxx20.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,7 @@ thread type_traits
926926
thread version
927927
tuple compare
928928
tuple cstddef
929+
tuple cstdint
929930
tuple exception
930931
tuple iosfwd
931932
tuple new

libcxx/test/libcxx/transitive_includes/cxx23.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ exception typeinfo
161161
exception version
162162
execution version
163163
expected cstddef
164+
expected cstdint
164165
expected initializer_list
165166
expected new
166167
expected version
@@ -494,6 +495,7 @@ regex typeinfo
494495
regex vector
495496
regex version
496497
scoped_allocator cstddef
498+
scoped_allocator cstdint
497499
scoped_allocator limits
498500
scoped_allocator new
499501
scoped_allocator tuple
@@ -650,6 +652,7 @@ thread typeinfo
650652
thread version
651653
tuple compare
652654
tuple cstddef
655+
tuple cstdint
653656
tuple version
654657
type_traits cstddef
655658
type_traits cstdint
@@ -684,6 +687,7 @@ unordered_set tuple
684687
unordered_set version
685688
utility compare
686689
utility cstddef
690+
utility cstdint
687691
utility initializer_list
688692
utility limits
689693
utility version

libcxx/test/libcxx/transitive_includes/cxx26.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ exception typeinfo
161161
exception version
162162
execution version
163163
expected cstddef
164+
expected cstdint
164165
expected initializer_list
165166
expected new
166167
expected version
@@ -517,6 +518,7 @@ regex typeinfo
517518
regex vector
518519
regex version
519520
scoped_allocator cstddef
521+
scoped_allocator cstdint
520522
scoped_allocator limits
521523
scoped_allocator new
522524
scoped_allocator tuple
@@ -673,6 +675,7 @@ thread typeinfo
673675
thread version
674676
tuple compare
675677
tuple cstddef
678+
tuple cstdint
676679
tuple version
677680
type_traits cstddef
678681
type_traits cstdint
@@ -707,6 +710,7 @@ unordered_set tuple
707710
unordered_set version
708711
utility compare
709712
utility cstddef
713+
utility cstdint
710714
utility initializer_list
711715
utility limits
712716
utility version

0 commit comments

Comments
 (0)