@@ -17,53 +17,11 @@ import std_module;
17
17
18
18
namespace bounded {
19
19
20
- // https://quuxplusone.github.io/blog/2018/05/17/super-elider-round-2/
21
- template <typename T, typename Function>
22
- struct superconstructing_super_elider {
23
- static_assert (std::is_reference_v<Function>);
24
-
25
- constexpr explicit superconstructing_super_elider (Function function) noexcept :
26
- m_function(OPERATORS_FORWARD(function))
27
- {
28
- }
29
-
30
- // Deleting the move constructor limits the cases where this will silently
31
- // collide with an "accepts anything" constructor. For instance, this class
32
- // can be used with std::any.
33
- superconstructing_super_elider (superconstructing_super_elider &&) = delete ;
34
-
35
- constexpr operator T () && noexcept (noexcept (static_cast <T>(declval<Function>()()))) {
36
- return static_cast <T>(OPERATORS_FORWARD (m_function)());
37
- }
38
-
39
- private:
40
- Function m_function;
41
- };
42
-
43
- template <typename T>
44
- constexpr auto is_no_lazy_construction = false ;
45
-
46
- template <typename T>
47
- constexpr auto is_no_lazy_construction<no_lazy_construction<T>> = true ;
48
-
49
- template <typename T, typename Function>
50
- constexpr auto is_noexcept_construct_at = noexcept (static_cast <T>(declval<Function>()()));
51
-
52
- template <typename T, typename Function> requires is_no_lazy_construction<std::invoke_result_t <Function>>
53
- constexpr auto is_noexcept_construct_at<T, Function> = noexcept (static_cast <T>(declval<Function>()().value));
54
-
55
20
// https://github.com/llvm/llvm-project/issues/59513
56
21
struct construct_at_t {
57
22
template <non_const T, construct_function_for<T> Function>
58
- static constexpr auto operator ()(T & ref, Function && function) noexcept (is_noexcept_construct_at<T, Function>) -> T & {
59
- auto make = [&] {
60
- if constexpr (is_no_lazy_construction<std::invoke_result_t <Function>>) {
61
- return OPERATORS_FORWARD (function)().value ;
62
- } else {
63
- return superconstructing_super_elider<T, Function &&>(OPERATORS_FORWARD (function));
64
- }
65
- };
66
- return *std::construct_at (std::addressof (ref), make ());
23
+ static constexpr auto operator ()(T & ref, Function && function) noexcept (noexcept (static_cast <T>(declval<Function>()()))) -> T & {
24
+ return *::new (static_cast <void *>(std::addressof (ref))) T (std::invoke (OPERATORS_FORWARD (function)));
67
25
}
68
26
};
69
27
export constexpr auto construct_at = construct_at_t ();
@@ -92,7 +50,7 @@ union u {
92
50
93
51
static_assert ([]{
94
52
auto x = u ();
95
- bounded::construct_at (x.a , [] { return bounded::no_lazy_construction ( accepts_anything (5 ) ); });
53
+ bounded::construct_at (x.a , [] { return accepts_anything (5 ); });
96
54
return true ;
97
55
}());
98
56
@@ -108,13 +66,4 @@ struct convert_to_int_throws {
108
66
auto make_convert_to_int_throws () noexcept -> convert_to_int_throws;
109
67
static_assert (!noexcept (bounded::construct_at(bounded::declval<int &>(), make_convert_to_int_throws)));
110
68
111
- auto make_no_lazy_construction_int_noexcept () noexcept -> bounded::no_lazy_construction<int>;
112
- static_assert (noexcept (bounded::construct_at(bounded::declval<int &>(), make_no_lazy_construction_int_noexcept)));
113
-
114
- auto make_no_lazy_construction_int_throws () -> bounded::no_lazy_construction<int>;
115
- static_assert (!noexcept (bounded::construct_at(bounded::declval<int &>(), make_no_lazy_construction_int_throws)));
116
-
117
- auto make_no_lazy_construction_convert_to_int_throws () noexcept -> bounded::no_lazy_construction<convert_to_int_throws>;
118
- static_assert (!noexcept (bounded::construct_at(bounded::declval<int &>(), make_no_lazy_construction_convert_to_int_throws)));
119
-
120
69
} // namespace
0 commit comments