@@ -19,6 +19,79 @@ import mcpplibs.primitives.policy.traits;
1919import mcpplibs.primitives.policy.handler;
2020import mcpplibs.primitives.underlying.traits;
2121
22+ namespace mcpplibs ::primitives::policy::details {
23+
24+ template <typename T, bool = std::is_trivially_copyable_v<T>>
25+ struct atomic_ref_alignment_compatible : std::false_type {};
26+
27+ template <typename T>
28+ struct atomic_ref_alignment_compatible <T, true >
29+ : std::bool_constant<(alignof (T) >=
30+ std::atomic_ref<T>::required_alignment)> {};
31+
32+ template <typename T>
33+ inline constexpr bool atomic_ref_compatible_v =
34+ atomic_ref_alignment_compatible<T>::value;
35+
36+ template <typename T> constexpr void assert_atomic_ref_compatible () {
37+ static_assert (std::is_trivially_copyable_v<T>,
38+ " concurrency::handler atomic access requires trivially "
39+ " copyable CommonRep" );
40+ static_assert (
41+ atomic_ref_alignment_compatible<T>::value,
42+ " concurrency::handler atomic access requires alignof(CommonRep) to "
43+ " satisfy std::atomic_ref<CommonRep>::required_alignment" );
44+ }
45+
46+ template <typename T>
47+ concept has_underlying_rep_not_equal =
48+ underlying_type<T> &&
49+ requires (T const &lhs, T const &rhs) {
50+ {
51+ underlying::traits<std::remove_cv_t <T>>::to_rep (lhs) !=
52+ underlying::traits<std::remove_cv_t <T>>::to_rep (rhs)
53+ } -> std::convertible_to<bool >;
54+ };
55+
56+ template <typename T>
57+ inline constexpr bool none_compare_exchange_available_v =
58+ has_underlying_rep_not_equal<T>;
59+
60+ template <typename OpTag>
61+ inline constexpr bool is_arithmetic_operation_v =
62+ operations::op_has_capability_v<OpTag, operations::capability::arithmetic>;
63+
64+ template <typename T>
65+ inline constexpr bool is_boolean_or_character_v = std_bool<T> || std_char<T>;
66+
67+ template <typename OpTag, typename LhsRep, typename RhsRep>
68+ inline constexpr bool rejects_arithmetic_for_boolean_or_character_v =
69+ is_arithmetic_operation_v<OpTag> &&
70+ (is_boolean_or_character_v<LhsRep> || is_boolean_or_character_v<RhsRep>);
71+
72+ template <typename LhsRep, typename RhsRep>
73+ inline constexpr bool has_non_void_common_rep_v =
74+ has_common_rep<LhsRep, RhsRep> &&
75+ !std::same_as<common_rep_t <LhsRep, RhsRep>, void >;
76+
77+ template <typename LhsRep, typename RhsRep>
78+ inline constexpr bool has_same_underlying_category_v =
79+ underlying::traits<std::remove_cv_t <LhsRep>>::enabled &&
80+ underlying::traits<std::remove_cv_t <RhsRep>>::enabled &&
81+ (underlying::traits<std::remove_cv_t <LhsRep>>::kind ==
82+ underlying::traits<std::remove_cv_t <RhsRep>>::kind);
83+
84+ template <typename T>
85+ auto atomic_ref_load (T const &value, std::memory_order order) noexcept -> T {
86+ assert_atomic_ref_compatible<T>();
87+ // libc++ rejects std::atomic_ref<const T>; load through a non-mutating view.
88+ auto &mutable_value = const_cast <T &>(value);
89+ std::atomic_ref<T> ref (mutable_value);
90+ return ref.load (order);
91+ }
92+
93+ } // namespace mcpplibs::primitives::policy::details
94+
2295export namespace mcpplibs ::primitives::policy {
2396
2497namespace value {
@@ -138,79 +211,6 @@ using error = error::throwing;
138211using concurrency = concurrency::none;
139212} // namespace defaults
140213
141- namespace details {
142-
143- template <typename T, bool = std::is_trivially_copyable_v<T>>
144- struct atomic_ref_alignment_compatible : std::false_type {};
145-
146- template <typename T>
147- struct atomic_ref_alignment_compatible <T, true >
148- : std::bool_constant<(alignof (T) >=
149- std::atomic_ref<T>::required_alignment)> {};
150-
151- template <typename T>
152- inline constexpr bool atomic_ref_compatible_v =
153- atomic_ref_alignment_compatible<T>::value;
154-
155- template <typename T> constexpr void assert_atomic_ref_compatible () {
156- static_assert (std::is_trivially_copyable_v<T>,
157- " concurrency::handler atomic access requires trivially "
158- " copyable CommonRep" );
159- static_assert (
160- atomic_ref_alignment_compatible<T>::value,
161- " concurrency::handler atomic access requires alignof(CommonRep) to "
162- " satisfy std::atomic_ref<CommonRep>::required_alignment" );
163- }
164-
165- template <typename T>
166- concept has_underlying_rep_not_equal =
167- underlying_type<T> &&
168- requires (T const &lhs, T const &rhs) {
169- {
170- underlying::traits<std::remove_cv_t <T>>::to_rep (lhs) !=
171- underlying::traits<std::remove_cv_t <T>>::to_rep (rhs)
172- } -> std::convertible_to<bool >;
173- };
174-
175- template <typename T>
176- inline constexpr bool none_compare_exchange_available_v =
177- has_underlying_rep_not_equal<T>;
178-
179- template <typename OpTag>
180- inline constexpr bool is_arithmetic_operation_v =
181- operations::op_has_capability_v<OpTag, operations::capability::arithmetic>;
182-
183- template <typename T>
184- inline constexpr bool is_boolean_or_character_v = std_bool<T> || std_char<T>;
185-
186- template <typename OpTag, typename LhsRep, typename RhsRep>
187- inline constexpr bool rejects_arithmetic_for_boolean_or_character_v =
188- is_arithmetic_operation_v<OpTag> &&
189- (is_boolean_or_character_v<LhsRep> || is_boolean_or_character_v<RhsRep>);
190-
191- template <typename LhsRep, typename RhsRep>
192- inline constexpr bool has_non_void_common_rep_v =
193- has_common_rep<LhsRep, RhsRep> &&
194- !std::same_as<common_rep_t <LhsRep, RhsRep>, void >;
195-
196- template <typename LhsRep, typename RhsRep>
197- inline constexpr bool has_same_underlying_category_v =
198- underlying::traits<std::remove_cv_t <LhsRep>>::enabled &&
199- underlying::traits<std::remove_cv_t <RhsRep>>::enabled &&
200- (underlying::traits<std::remove_cv_t <LhsRep>>::kind ==
201- underlying::traits<std::remove_cv_t <RhsRep>>::kind);
202-
203- template <typename T>
204- auto atomic_ref_load (T const &value, std::memory_order order) noexcept -> T {
205- assert_atomic_ref_compatible<T>();
206- // libc++ rejects std::atomic_ref<const T>; load through a non-mutating view.
207- auto &mutable_value = const_cast <T &>(value);
208- std::atomic_ref<T> ref (mutable_value);
209- return ref.load (order);
210- }
211-
212- } // namespace details
213-
214214// Default protocol specializations.
215215template <operations::operation OpTag, typename LhsRep, typename RhsRep>
216216struct type ::handler<type::strict, OpTag, LhsRep, RhsRep> {
0 commit comments