Skip to content

Commit 65f0ffa

Browse files
committed
[libc++] Add tombstone traits to use in optional, variant
1 parent 8b3a124 commit 65f0ffa

File tree

25 files changed

+664
-16
lines changed

25 files changed

+664
-16
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ set(files
596596
__memory/swap_allocator.h
597597
__memory/temp_value.h
598598
__memory/temporary_buffer.h
599+
__memory/tombstone_traits.h
599600
__memory/uninitialized_algorithms.h
600601
__memory/unique_ptr.h
601602
__memory/unique_temporary_buffer.h

libcxx/include/__configuration/abi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY
8484
# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW
8585
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
86+
# define _LIBCPP_ABI_OPTIONAL_USE_TOMBSTONE_TRAITS
8687

8788
#elif _LIBCPP_ABI_VERSION == 1
8889
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
@@ -101,6 +102,9 @@
101102
# if defined(__FreeBSD__)
102103
# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
103104
# endif
105+
106+
// TODO: This shouldn't be in the final commit - this just to test the changes across all the different configurations
107+
# define _LIBCPP_ABI_OPTIONAL_USE_TOMBSTONE_TRAITS
104108
#endif
105109

106110
// TODO(LLVM 22): Remove this check

libcxx/include/__functional/reference_wrapper.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include <__compare/synth_three_way.h>
1414
#include <__concepts/convertible_to.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/common_reference.h>
1921
#include <__type_traits/desugars_to.h>
2022
#include <__type_traits/enable_if.h>
@@ -125,7 +127,27 @@ class reference_wrapper : public __weak_result_type<_Tp> {
125127
#if _LIBCPP_STD_VER >= 17
126128
template <class _Tp>
127129
reference_wrapper(_Tp&) -> reference_wrapper<_Tp>;
128-
#endif
130+
131+
template <class _Tp>
132+
struct __tombstone_traits<reference_wrapper<_Tp>> {
133+
// reference_wrapper<_Tp> is conceptually that same as _Tp& and can only be constructed from a _Tp&. Since references
134+
// can never be null, reference_wrapper can also never be null, allowing us to use it as an invalid state.
135+
136+
template <class _Payload, size_t _Np>
137+
struct __representation;
138+
139+
template <class _Payload>
140+
struct __representation<_Payload, 0> {
141+
template <class... _Args>
142+
constexpr __representation(_Args&&... __args) : __payload_(std::forward<_Args>(__args)...), __value_(nullptr) {}
143+
144+
bool __is_tombstone() { return __value_ == nullptr; }
145+
146+
_LIBCPP_NO_UNIQUE_ADDRESS _Payload __payload_;
147+
_Tp* __value_;
148+
};
149+
};
150+
#endif // _LIBCPP_STD_VER >= 17
129151

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

libcxx/include/__locale

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# include <__locale_dir/locale_base_api.h>
1818
# include <__memory/addressof.h>
1919
# include <__memory/shared_count.h>
20+
# include <__memory/tombstone_traits.h>
2021
# include <__mutex/once_flag.h>
2122
# include <__type_traits/make_unsigned.h>
2223
# include <__utility/no_destroy.h>
@@ -113,8 +114,9 @@ public:
113114
static locale global(const locale&);
114115
static const locale& classic();
115116

116-
private:
117117
class __imp;
118+
119+
private:
118120
__imp* __locale_;
119121

120122
template <class>
@@ -130,7 +132,18 @@ private:
130132
friend bool has_facet(const locale&) _NOEXCEPT;
131133
template <class _Facet>
132134
friend const _Facet& use_facet(const locale&);
135+
136+
friend struct __tombstone_traits<locale>;
137+
};
138+
139+
#if _LIBCPP_STD_VER >= 17
140+
// Derived from the void* specialization, since __imp is never defined.
141+
template <>
142+
struct __tombstone_traits<locale> : __tombstone_traits_assume_aligned_pointer<void*> {
143+
static_assert(__builtin_offsetof(locale, __locale_) == 0);
144+
static_assert(sizeof(locale) == sizeof(void*));
133145
};
146+
#endif
134147

135148
class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count {
136149
protected:

libcxx/include/__memory/shared_ptr.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <__memory/destroy.h>
3333
#include <__memory/pointer_traits.h>
3434
#include <__memory/shared_count.h>
35+
#include <__memory/tombstone_traits.h>
3536
#include <__memory/uninitialized_algorithms.h>
3637
#include <__memory/unique_ptr.h>
3738
#include <__type_traits/add_reference.h>
@@ -689,14 +690,25 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
689690
friend class shared_ptr;
690691
template <class _Up>
691692
friend class weak_ptr;
693+
694+
friend struct __tombstone_traits<shared_ptr<_Tp> >;
692695
};
693696

694-
#if _LIBCPP_STD_VER >= 17
697+
#if _LIBCPP_STD_VER >= 17 && 0
695698
template <class _Tp>
696699
shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
697700
template <class _Tp, class _Dp>
698701
shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
699-
#endif
702+
703+
template <class _Tp>
704+
struct __tombstone_traits<shared_ptr<_Tp>> {
705+
static constexpr auto __disengaged_value_ =
706+
__tombstone_traits_assume_aligned_pointer<__shared_weak_count*>::__disengaged_value_;
707+
static constexpr size_t __is_disengaged_offset_ =
708+
__builtin_offsetof(shared_ptr<_Tp>, __cntrl_) +
709+
__tombstone_traits_assume_aligned_pointer<__shared_weak_count*>::__is_disengaged_offset_;
710+
};
711+
#endif // _LIBCPP_STD_VER >= 17
700712

701713
//
702714
// std::allocate_shared and std::make_shared
@@ -1242,12 +1254,19 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
12421254
friend class weak_ptr;
12431255
template <class _Up>
12441256
friend class shared_ptr;
1257+
1258+
friend struct __tombstone_traits<weak_ptr<_Tp> >;
12451259
};
12461260

12471261
#if _LIBCPP_STD_VER >= 17
12481262
template <class _Tp>
12491263
weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1250-
#endif
1264+
1265+
template <class _Tp>
1266+
struct __tombstone_traits<weak_ptr<_Tp>> {
1267+
1268+
};
1269+
#endif // _LIBCPP_STD_VER >= 17
12511270

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

0 commit comments

Comments
 (0)