Skip to content

Commit f20f4b9

Browse files
committed
[libc++] Simplify the implementation of __tuple_leaf
1 parent 51809e4 commit f20f4b9

File tree

8 files changed

+146
-154
lines changed

8 files changed

+146
-154
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ set(files
863863
__utility/as_lvalue.h
864864
__utility/auto_cast.h
865865
__utility/cmp.h
866+
__utility/conditional_no_unique_address.h
866867
__utility/convert_to_integral.h
867868
__utility/declval.h
868869
__utility/empty.h

libcxx/include/__expected/expected.h

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <__type_traits/remove_cv.h>
4141
#include <__type_traits/remove_cvref.h>
4242
#include <__utility/as_const.h>
43+
#include <__utility/conditional_no_unique_address.h>
4344
#include <__utility/exception_guard.h>
4445
#include <__utility/forward.h>
4546
#include <__utility/in_place.h>
@@ -81,55 +82,6 @@ _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) {
8182
# endif
8283
}
8384

84-
// If parameter type `_Tp` of `__conditional_no_unique_address` is neither
85-
// copyable nor movable, a constructor with this tag is provided. For that
86-
// constructor, the user has to provide a function and arguments. The function
87-
// must return an object of type `_Tp`. When the function is invoked by the
88-
// constructor, guaranteed copy elision kicks in and the `_Tp` is constructed
89-
// in place.
90-
struct __conditional_no_unique_address_invoke_tag {};
91-
92-
// This class implements an object with `[[no_unique_address]]` conditionally applied to it,
93-
// based on the value of `_NoUnique`.
94-
//
95-
// A member of this class must always have `[[no_unique_address]]` applied to
96-
// it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case
97-
// would not have any effect. In the `false` case, the `__v` is not
98-
// `[[no_unique_address]]`, so nullifies the effects of the "outer"
99-
// `[[no_unique_address]]` regarding data layout.
100-
//
101-
// If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`.
102-
template <bool _NoUnique, class _Tp>
103-
struct __conditional_no_unique_address;
104-
105-
template <class _Tp>
106-
struct __conditional_no_unique_address<true, _Tp> {
107-
template <class... _Args>
108-
_LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
109-
: __v(std::forward<_Args>(__args)...) {}
110-
111-
template <class _Func, class... _Args>
112-
_LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
113-
__conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
114-
: __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
115-
116-
_LIBCPP_NO_UNIQUE_ADDRESS _Tp __v;
117-
};
118-
119-
template <class _Tp>
120-
struct __conditional_no_unique_address<false, _Tp> {
121-
template <class... _Args>
122-
_LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args)
123-
: __v(std::forward<_Args>(__args)...) {}
124-
125-
template <class _Func, class... _Args>
126-
_LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(
127-
__conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
128-
: __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
129-
130-
_Tp __v;
131-
};
132-
13385
// This function returns whether the type `_Second` can be stuffed into the tail padding
13486
// of the `_First` type if both of them are given `[[no_unique_address]]`.
13587
template <class _First, class _Second>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___UTILITY_CONDITIONAL_NO_UNIQUE_ADDRESS_H
10+
#define _LIBCPP___UTILITY_CONDITIONAL_NO_UNIQUE_ADDRESS_H
11+
12+
#include <__config>
13+
#include <__type_traits/invoke.h>
14+
#include <__type_traits/is_swappable.h>
15+
#include <__utility/forward.h>
16+
#include <__utility/in_place.h>
17+
18+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19+
# pragma GCC system_header
20+
#endif
21+
22+
_LIBCPP_PUSH_MACROS
23+
#include <__undef_macros>
24+
25+
_LIBCPP_BEGIN_NAMESPACE_STD
26+
27+
// If parameter type `_Tp` of `__conditional_no_unique_address` is neither
28+
// copyable nor movable, a constructor with this tag is provided. For that
29+
// constructor, the user has to provide a function and arguments. The function
30+
// must return an object of type `_Tp`. When the function is invoked by the
31+
// constructor, guaranteed copy elision kicks in and the `_Tp` is constructed
32+
// in place.
33+
struct __conditional_no_unique_address_invoke_tag {};
34+
35+
// This class implements an object with `[[no_unique_address]]` conditionally applied to it,
36+
// based on the value of `_NoUnique`.
37+
//
38+
// A member of this class must always have `[[no_unique_address]]` applied to
39+
// it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case
40+
// would not have any effect. In the `false` case, the `__v` is not
41+
// `[[no_unique_address]]`, so nullifies the effects of the "outer"
42+
// `[[no_unique_address]]` regarding data layout.
43+
//
44+
// If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`.
45+
template <bool _NoUnique, class _Tp>
46+
struct __conditional_no_unique_address;
47+
48+
template <class _Tp>
49+
struct __conditional_no_unique_address<true, _Tp> {
50+
template <class... _Args>
51+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __conditional_no_unique_address(__in_place_t, _Args&&... __args)
52+
: __v(std::forward<_Args>(__args)...) {}
53+
54+
template <class _Func, class... _Args>
55+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __conditional_no_unique_address(
56+
__conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
57+
: __v(std::__invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
58+
59+
_LIBCPP_NO_UNIQUE_ADDRESS _Tp __v;
60+
};
61+
62+
template <class _Tp>
63+
struct __conditional_no_unique_address<false, _Tp> {
64+
template <class... _Args>
65+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __conditional_no_unique_address(__in_place_t, _Args&&... __args)
66+
: __v(std::forward<_Args>(__args)...) {}
67+
68+
template <class _Func, class... _Args>
69+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __conditional_no_unique_address(
70+
__conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args)
71+
: __v(std::__invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {}
72+
73+
_Tp __v;
74+
};
75+
76+
template <bool _NoUnique, class _Tp>
77+
void swap(__conditional_no_unique_address<_NoUnique, _Tp>& __lhs,
78+
__conditional_no_unique_address<_NoUnique, _Tp>& __rhs) _NOEXCEPT_(__is_swappable_v<_Tp>) {
79+
using std::swap;
80+
swap(__lhs.__v, __rhs.__v);
81+
}
82+
83+
_LIBCPP_END_NAMESPACE_STD
84+
85+
_LIBCPP_POP_MACROS
86+
87+
#endif // _LIBCPP___UTILITY_CONDITIONAL_NO_UNIQUE_ADDRESS_H

libcxx/include/__utility/in_place.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ using __is_inplace_index = __is_inplace_index_imp<__remove_cvref_t<_Tp>>;
5959

6060
#endif // _LIBCPP_STD_VER >= 17
6161

62+
struct __in_place_t {
63+
explicit __in_place_t() = default;
64+
#if _LIBCPP_STD_VER >= 17
65+
_LIBCPP_HIDE_FROM_ABI constexpr __in_place_t(in_place_t) {}
66+
#endif
67+
};
68+
inline const __in_place_t __in_place;
69+
6270
_LIBCPP_END_NAMESPACE_STD
6371

6472
#endif // _LIBCPP___UTILITY_IN_PLACE_H

libcxx/include/module.modulemap

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1988,36 +1988,37 @@ module std [system] {
19881988
}
19891989

19901990
module utility {
1991-
module as_const { header "__utility/as_const.h" }
1992-
module as_lvalue { header "__utility/as_lvalue.h" }
1993-
module auto_cast {
1991+
module as_const { header "__utility/as_const.h" }
1992+
module as_lvalue { header "__utility/as_lvalue.h" }
1993+
module auto_cast {
19941994
header "__utility/auto_cast.h"
19951995
export std_core.type_traits.decay // the macro expansion uses that trait
19961996
}
1997-
module cmp { header "__utility/cmp.h" }
1998-
module convert_to_integral { header "__utility/convert_to_integral.h" }
1999-
module exception_guard { header "__utility/exception_guard.h" }
2000-
module exchange { header "__utility/exchange.h" }
2001-
module forward_like { header "__utility/forward_like.h" }
1997+
module cmp { header "__utility/cmp.h" }
1998+
module conditional_no_unique_address { header "__utility/conditional_no_unique_address.h" }
1999+
module convert_to_integral { header "__utility/convert_to_integral.h" }
2000+
module exception_guard { header "__utility/exception_guard.h" }
2001+
module exchange { header "__utility/exchange.h" }
2002+
module forward_like { header "__utility/forward_like.h" }
20022003
module in_place {
20032004
header "__utility/in_place.h"
20042005
export std_core.type_traits.integral_constant
20052006
}
2006-
module integer_sequence { header "__utility/integer_sequence.h" }
2007-
module is_pointer_in_range { header "__utility/is_pointer_in_range.h" }
2008-
module is_valid_range { header "__utility/is_valid_range.h" }
2009-
module move { header "__utility/move.h" }
2010-
module no_destroy { header "__utility/no_destroy.h" }
2011-
module pair { header "__utility/pair.h" }
2012-
module piecewise_construct { header "__utility/piecewise_construct.h" }
2013-
module priority_tag { header "__utility/priority_tag.h" }
2014-
module private_constructor_tag { header "__utility/private_constructor_tag.h" }
2015-
module rel_ops { header "__utility/rel_ops.h" }
2016-
module scope_guard { header "__utility/scope_guard.h" }
2017-
module small_buffer { header "__utility/small_buffer.h" }
2018-
module swap { header "__utility/swap.h" }
2019-
module to_underlying { header "__utility/to_underlying.h" }
2020-
module unreachable { header "__utility/unreachable.h" }
2007+
module integer_sequence { header "__utility/integer_sequence.h" }
2008+
module is_pointer_in_range { header "__utility/is_pointer_in_range.h" }
2009+
module is_valid_range { header "__utility/is_valid_range.h" }
2010+
module move { header "__utility/move.h" }
2011+
module no_destroy { header "__utility/no_destroy.h" }
2012+
module pair { header "__utility/pair.h" }
2013+
module piecewise_construct { header "__utility/piecewise_construct.h" }
2014+
module priority_tag { header "__utility/priority_tag.h" }
2015+
module private_constructor_tag { header "__utility/private_constructor_tag.h" }
2016+
module rel_ops { header "__utility/rel_ops.h" }
2017+
module scope_guard { header "__utility/scope_guard.h" }
2018+
module small_buffer { header "__utility/small_buffer.h" }
2019+
module swap { header "__utility/swap.h" }
2020+
module to_underlying { header "__utility/to_underlying.h" }
2021+
module unreachable { header "__utility/unreachable.h" }
20212022

20222023
header "utility"
20232024
export *

0 commit comments

Comments
 (0)