11module ;
2+ #include < atomic>
23#include < concepts>
34#include < exception>
45#include < expected>
56#include < stdexcept>
67#include < string>
78#include < type_traits>
89
9-
1010export module mcpplibs.primitives.policy.impl;
1111
1212import mcpplibs.primitives.operations.traits;
@@ -37,7 +37,10 @@ struct terminate {};
3737
3838namespace concurrency {
3939struct none {};
40- struct atomic {};
40+ struct fenced {};
41+ struct fenced_relaxed {};
42+ struct fenced_acq_rel {};
43+ struct fenced_seq_cst {};
4144} // namespace concurrency
4245
4346template <> struct traits <value::checked> {
@@ -100,8 +103,26 @@ template <> struct traits<concurrency::none> {
100103 static constexpr auto kind = category::concurrency;
101104};
102105
103- template <> struct traits <concurrency::atomic> {
104- using policy_type = concurrency::atomic;
106+ template <> struct traits <concurrency::fenced> {
107+ using policy_type = concurrency::fenced;
108+ static constexpr bool enabled = true ;
109+ static constexpr auto kind = category::concurrency;
110+ };
111+
112+ template <> struct traits <concurrency::fenced_relaxed> {
113+ using policy_type = concurrency::fenced_relaxed;
114+ static constexpr bool enabled = true ;
115+ static constexpr auto kind = category::concurrency;
116+ };
117+
118+ template <> struct traits <concurrency::fenced_acq_rel> {
119+ using policy_type = concurrency::fenced_acq_rel;
120+ static constexpr bool enabled = true ;
121+ static constexpr auto kind = category::concurrency;
122+ };
123+
124+ template <> struct traits <concurrency::fenced_seq_cst> {
125+ using policy_type = concurrency::fenced_seq_cst;
105126 static constexpr bool enabled = true ;
106127 static constexpr auto kind = category::concurrency;
107128};
@@ -189,7 +210,7 @@ struct concurrency::handler<concurrency::none, OpTag, CommonRep, ErrorPayload> {
189210
190211template <operations::operation OpTag, typename CommonRep,
191212 typename ErrorPayload>
192- struct concurrency ::handler<concurrency::atomic , OpTag, CommonRep,
213+ struct concurrency ::handler<concurrency::fenced , OpTag, CommonRep,
193214 ErrorPayload> {
194215 static constexpr bool enabled = true ;
195216 static constexpr bool requires_external_sync = true ;
@@ -200,10 +221,172 @@ struct concurrency::handler<concurrency::atomic, OpTag, CommonRep,
200221 injection_type out{};
201222 out.fence_before = true ;
202223 out.fence_after = true ;
224+ out.order_before = std::memory_order_seq_cst;
225+ out.order_after = std::memory_order_seq_cst;
203226 return out;
204227 }
205228};
206229
230+ template <operations::operation OpTag, typename CommonRep,
231+ typename ErrorPayload>
232+ struct concurrency ::handler<concurrency::fenced_relaxed, OpTag, CommonRep,
233+ ErrorPayload> {
234+ static constexpr bool enabled = true ;
235+ static constexpr bool requires_external_sync = true ;
236+ using injection_type = concurrency::injection;
237+ using result_type = std::expected<CommonRep, ErrorPayload>;
238+
239+ static constexpr auto inject () noexcept -> injection_type {
240+ injection_type out{};
241+ out.fence_before = true ;
242+ out.fence_after = true ;
243+ out.order_before = std::memory_order_relaxed;
244+ out.order_after = std::memory_order_relaxed;
245+ return out;
246+ }
247+ };
248+
249+ template <operations::operation OpTag, typename CommonRep,
250+ typename ErrorPayload>
251+ struct concurrency ::handler<concurrency::fenced_acq_rel, OpTag, CommonRep,
252+ ErrorPayload> {
253+ static constexpr bool enabled = true ;
254+ static constexpr bool requires_external_sync = true ;
255+ using injection_type = concurrency::injection;
256+ using result_type = std::expected<CommonRep, ErrorPayload>;
257+
258+ static constexpr auto inject () noexcept -> injection_type {
259+ injection_type out{};
260+ out.fence_before = true ;
261+ out.fence_after = true ;
262+ out.order_before = std::memory_order_acquire;
263+ out.order_after = std::memory_order_release;
264+ return out;
265+ }
266+ };
267+
268+ template <operations::operation OpTag, typename CommonRep,
269+ typename ErrorPayload>
270+ struct concurrency ::handler<concurrency::fenced_seq_cst, OpTag, CommonRep,
271+ ErrorPayload> {
272+ static constexpr bool enabled = true ;
273+ static constexpr bool requires_external_sync = true ;
274+ using injection_type = concurrency::injection;
275+ using result_type = std::expected<CommonRep, ErrorPayload>;
276+
277+ static constexpr auto inject () noexcept -> injection_type {
278+ injection_type out{};
279+ out.fence_before = true ;
280+ out.fence_after = true ;
281+ out.order_before = std::memory_order_seq_cst;
282+ out.order_after = std::memory_order_seq_cst;
283+ return out;
284+ }
285+ };
286+
287+ template <typename CommonRep, typename ErrorPayload>
288+ struct concurrency ::handler<concurrency::fenced, void , CommonRep,
289+ ErrorPayload> {
290+ static constexpr bool enabled = std::is_trivially_copyable_v<CommonRep>;
291+ using injection_type = concurrency::injection;
292+ using result_type = std::expected<CommonRep, ErrorPayload>;
293+
294+ static auto load (CommonRep const &value) noexcept -> CommonRep {
295+ std::atomic_ref<CommonRep const > ref (value);
296+ return ref.load (std::memory_order_seq_cst);
297+ }
298+
299+ static auto store (CommonRep &value, CommonRep desired) noexcept -> void {
300+ std::atomic_ref<CommonRep> ref (value);
301+ ref.store (desired, std::memory_order_seq_cst);
302+ }
303+
304+ static auto compare_exchange (CommonRep &value, CommonRep &expected,
305+ CommonRep desired) noexcept -> bool {
306+ std::atomic_ref<CommonRep> ref (value);
307+ return ref.compare_exchange_strong (expected, desired,
308+ std::memory_order_seq_cst,
309+ std::memory_order_seq_cst);
310+ }
311+ };
312+
313+ template <typename CommonRep, typename ErrorPayload>
314+ struct concurrency ::handler<concurrency::fenced_relaxed, void , CommonRep,
315+ ErrorPayload> {
316+ static constexpr bool enabled = std::is_trivially_copyable_v<CommonRep>;
317+ using injection_type = concurrency::injection;
318+ using result_type = std::expected<CommonRep, ErrorPayload>;
319+
320+ static auto load (CommonRep const &value) noexcept -> CommonRep {
321+ std::atomic_ref<CommonRep const > ref (value);
322+ return ref.load (std::memory_order_relaxed);
323+ }
324+
325+ static auto store (CommonRep &value, CommonRep desired) noexcept -> void {
326+ std::atomic_ref<CommonRep> ref (value);
327+ ref.store (desired, std::memory_order_relaxed);
328+ }
329+
330+ static auto compare_exchange (CommonRep &value, CommonRep &expected,
331+ CommonRep desired) noexcept -> bool {
332+ std::atomic_ref<CommonRep> ref (value);
333+ return ref.compare_exchange_strong (expected, desired,
334+ std::memory_order_relaxed,
335+ std::memory_order_relaxed);
336+ }
337+ };
338+
339+ template <typename CommonRep, typename ErrorPayload>
340+ struct concurrency ::handler<concurrency::fenced_acq_rel, void , CommonRep,
341+ ErrorPayload> {
342+ static constexpr bool enabled = std::is_trivially_copyable_v<CommonRep>;
343+ using injection_type = concurrency::injection;
344+ using result_type = std::expected<CommonRep, ErrorPayload>;
345+
346+ static auto load (CommonRep const &value) noexcept -> CommonRep {
347+ std::atomic_ref<CommonRep const > ref (value);
348+ return ref.load (std::memory_order_acquire);
349+ }
350+
351+ static auto store (CommonRep &value, CommonRep desired) noexcept -> void {
352+ std::atomic_ref<CommonRep> ref (value);
353+ ref.store (desired, std::memory_order_release);
354+ }
355+
356+ static auto compare_exchange (CommonRep &value, CommonRep &expected,
357+ CommonRep desired) noexcept -> bool {
358+ std::atomic_ref<CommonRep> ref (value);
359+ return ref.compare_exchange_strong (expected, desired,
360+ std::memory_order_acq_rel,
361+ std::memory_order_acquire);
362+ }
363+ };
364+
365+ template <typename CommonRep, typename ErrorPayload>
366+ struct concurrency ::handler<concurrency::fenced_seq_cst, void , CommonRep,
367+ ErrorPayload> {
368+ static constexpr bool enabled = std::is_trivially_copyable_v<CommonRep>;
369+ using injection_type = concurrency::injection;
370+ using result_type = std::expected<CommonRep, ErrorPayload>;
371+
372+ static auto load (CommonRep const &value) noexcept -> CommonRep {
373+ return concurrency::handler<concurrency::fenced, void , CommonRep,
374+ ErrorPayload>::load (value);
375+ }
376+
377+ static auto store (CommonRep &value, CommonRep desired) noexcept -> void {
378+ concurrency::handler<concurrency::fenced, void , CommonRep,
379+ ErrorPayload>::store (value, desired);
380+ }
381+
382+ static auto compare_exchange (CommonRep &value, CommonRep &expected,
383+ CommonRep desired) noexcept -> bool {
384+ return concurrency::handler<concurrency::fenced, void , CommonRep,
385+ ErrorPayload>::compare_exchange (value, expected,
386+ desired);
387+ }
388+ };
389+
207390template <operations::operation OpTag, typename CommonRep,
208391 typename ErrorPayload>
209392struct value ::handler<value::checked, OpTag, CommonRep, ErrorPayload> {
0 commit comments