Skip to content

Commit 01099c9

Browse files
committed
[libc++] Annotate the data member of variant with no_unique_address attribute.
This allows clients to reuse tail padding after the index (if any), by applying [[no_unique_address]] to variant fields.
1 parent 082598a commit 01099c9

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

libcxx/include/__configuration/abi.h

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
// Use the smallest possible integer type to represent the index of the variant.
5858
// Previously libc++ used "unsigned int" exclusively.
5959
# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
60+
// Allow to reuse tail padding after the index of the variant with [[no_unique_address]] attribute.
61+
# define _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
6062
// Unstable attempt to provide a more optimized std::function
6163
# define _LIBCPP_ABI_OPTIMIZED_FUNCTION
6264
// All the regex constants must be distinct and nonzero.

libcxx/include/variant

+5-1
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,11 @@ public:
13191319
# endif
13201320

13211321
private:
1322-
__variant_detail::__impl<_Types...> __impl_;
1322+
# ifdef _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
1323+
_LIBCPP_NO_UNIQUE_ADDRESS
1324+
# endif // _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
1325+
__variant_detail::__impl<_Types...>
1326+
__impl_;
13231327

13241328
friend struct __variant_detail::__access::__variant;
13251329
friend struct __variant_detail::__visitation::__variant;

libcxx/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ struct type_with_index {
7070
#endif
7171
};
7272

73+
struct alignas(16) A16 {};
74+
struct VariantWithNoUniqueAddress {
75+
TEST_NO_UNIQUE_ADDRESS std::variant<A16> a;
76+
bool b;
77+
};
78+
struct VariantWithoutNoUniqueAddress {
79+
std::variant<A16> a;
80+
bool b;
81+
};
82+
constexpr bool ExpectSmallerSizeWithNoUniqueAddress =
83+
#ifdef _LIBCPP_ABI_VARIANT_NO_UNIQUE_ADDRESS_OPTIMIZATION
84+
true;
85+
#else
86+
false;
87+
#endif
88+
7389
int main(int, char**) {
7490
test_index_type<unsigned char>();
7591
// This won't compile due to template depth issues.
@@ -84,5 +100,8 @@ int main(int, char**) {
84100
static_assert(sizeof(std::variant<char, int, long>) == sizeof(type_with_index<long>));
85101
static_assert(sizeof(std::variant<std::size_t, std::size_t, std::size_t>) == sizeof(type_with_index<std::size_t>));
86102

103+
static_assert((sizeof(VariantWithNoUniqueAddress) < sizeof(VariantWithoutNoUniqueAddress)) ==
104+
ExpectSmallerSizeWithNoUniqueAddress);
105+
87106
return 0;
88107
}

0 commit comments

Comments
 (0)