Skip to content

Commit f67cde6

Browse files
committed
[libc++] Add tombstone traits to use in optional, variant
1 parent e8b7d8b commit f67cde6

File tree

16 files changed

+579
-7
lines changed

16 files changed

+579
-7
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ set(files
560560
__memory/swap_allocator.h
561561
__memory/temp_value.h
562562
__memory/temporary_buffer.h
563+
__memory/tombstone_traits.h
563564
__memory/uninitialized_algorithms.h
564565
__memory/unique_ptr.h
565566
__memory/unique_temporary_buffer.h

libcxx/include/__configuration/abi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@
124124
// This setting disables the addition of such artificial padding, leading to a more optimal
125125
// representation for several types.
126126
# define _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING
127+
// Use __tombstone_traits to optimize the memory layout of std::optional.
128+
# define _LIBCPP_ABI_OPTIONAL_USE_TOMBSTONE_TRAITS
127129
#elif _LIBCPP_ABI_VERSION == 1
128130
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
129131
// Enable compiling copies of now inline methods into the dylib to support
@@ -141,6 +143,9 @@
141143
# if defined(__FreeBSD__) && __FreeBSD__ < 14
142144
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
143145
# endif
146+
147+
// TODO: This shouldn't be in the final commit - this just to test the changes across all the different configurations
148+
# define _LIBCPP_ABI_OPTIONAL_USE_TOMBSTONE_TRAITS
144149
#endif
145150

146151
// We had some bugs where we use [[no_unique_address]] together with construct_at,

libcxx/include/__functional/reference_wrapper.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@
1313
#include <__compare/synth_three_way.h>
1414
#include <__concepts/boolean_testable.h>
1515
#include <__config>
16+
#include <__cstddef/size_t.h>
1617
#include <__functional/weak_result_type.h>
1718
#include <__memory/addressof.h>
19+
#include <__memory/tombstone_traits.h>
1820
#include <__type_traits/enable_if.h>
1921
#include <__type_traits/invoke.h>
2022
#include <__type_traits/is_const.h>
2123
#include <__type_traits/remove_cvref.h>
2224
#include <__type_traits/void_t.h>
2325
#include <__utility/declval.h>
2426
#include <__utility/forward.h>
27+
#include <cstdint>
2528

2629
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2730
# pragma GCC system_header
@@ -120,7 +123,13 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> {
120123
#if _LIBCPP_STD_VER >= 17
121124
template <class _Tp>
122125
reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
123-
#endif
126+
127+
template <class _Tp>
128+
struct __tombstone_traits<reference_wrapper<_Tp>> {
129+
static constexpr uintptr_t __disengaged_value_ = __builtin_offsetof(reference_wrapper<_Tp>, __f_);
130+
static constexpr size_t __is_disengaged_offset_ = 0;
131+
};
132+
#endif // _LIBCPP_STD_VER >= 17
124133

125134
template <class _Tp>
126135
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT {

libcxx/include/__locale

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <__config>
1414
#include <__locale_dir/locale_base_api.h>
1515
#include <__memory/shared_ptr.h> // __shared_count
16+
#include <__memory/tombstone_traits.h>
1617
#include <__mutex/once_flag.h>
1718
#include <__type_traits/make_unsigned.h>
1819
#include <__utility/no_destroy.h>
@@ -112,8 +113,17 @@ private:
112113
friend bool has_facet(const locale&) _NOEXCEPT;
113114
template <class _Facet>
114115
friend const _Facet& use_facet(const locale&);
116+
117+
friend struct __tombstone_traits<locale>;
115118
};
116119

120+
#if _LIBCPP_STD_VER >= 17
121+
template <>
122+
struct __tombstone_traits<locale> : __tombstone_traits_assume_aligned_pointer {
123+
static_assert(__builtin_offsetof(locale, __locale_) == 0);
124+
};
125+
#endif
126+
117127
class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count {
118128
protected:
119129
_LIBCPP_HIDE_FROM_ABI explicit facet(size_t __refs = 0) : __shared_count(static_cast<long>(__refs) - 1) {}

libcxx/include/__memory/shared_ptr.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <__memory/compressed_pair.h>
3131
#include <__memory/construct_at.h>
3232
#include <__memory/pointer_traits.h>
33+
#include <__memory/tombstone_traits.h>
3334
#include <__memory/uninitialized_algorithms.h>
3435
#include <__memory/unique_ptr.h>
3536
#include <__type_traits/add_lvalue_reference.h>
@@ -824,14 +825,24 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr {
824825
friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
825826
template <class _Up>
826827
friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
828+
829+
friend struct __tombstone_traits<shared_ptr<_Tp>>;
827830
};
828831

829832
#if _LIBCPP_STD_VER >= 17
830833
template <class _Tp>
831834
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
832835
template <class _Tp, class _Dp>
833836
shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
834-
#endif
837+
838+
template <class _Tp>
839+
struct __tombstone_traits<shared_ptr<_Tp>> {
840+
static constexpr auto __disengaged_value_ = __tombstone_traits_assume_aligned_pointer::__disengaged_value_;
841+
static constexpr size_t __is_disengaged_offset_ =
842+
__builtin_offsetof(shared_ptr<_Tp>, __cntrl_) +
843+
__tombstone_traits_assume_aligned_pointer::__is_disengaged_offset_;
844+
};
845+
#endif // _LIBCPP_STD_VER >= 17
835846

836847
//
837848
// std::allocate_shared and std::make_shared
@@ -1376,12 +1387,21 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr {
13761387
friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
13771388
template <class _Up>
13781389
friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
1390+
1391+
friend struct __tombstone_traits<weak_ptr<_Tp>>;
13791392
};
13801393

13811394
#if _LIBCPP_STD_VER >= 17
13821395
template <class _Tp>
13831396
weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1384-
#endif
1397+
1398+
template <class _Tp>
1399+
struct __tombstone_traits<weak_ptr<_Tp>> {
1400+
static constexpr auto __disengaged_value_ = __tombstone_traits_assume_aligned_pointer::__disengaged_value_;
1401+
static constexpr size_t __is_disengaged_offset_ =
1402+
__builtin_offsetof(weak_ptr<_Tp>, __cntrl_) + __tombstone_traits_assume_aligned_pointer::__is_disengaged_offset_;
1403+
};
1404+
#endif // _LIBCPP_STD_VER >= 17
13851405

13861406
template <class _Tp>
13871407
inline _LIBCPP_CONSTEXPR weak_ptr<_Tp>::weak_ptr() _NOEXCEPT : __ptr_(nullptr), __cntrl_(nullptr) {}

0 commit comments

Comments
 (0)