@@ -6,18 +6,97 @@ export module mcpplibs.primitives.primitive.impl;
66
77import mcpplibs.primitives.underlying.traits;
88import mcpplibs.primitives.policy.traits;
9+ import mcpplibs.primitives.policy.impl;
10+ import mcpplibs.primitives.policy.handler;
911
1012export namespace mcpplibs ::primitives {
1113
14+ namespace details {
15+
16+ template <policy::policy_type... Policies> struct count_concurrency_policies ;
17+
18+ template <> struct count_concurrency_policies <> {
19+ static constexpr std::size_t value = 0 ;
20+ };
21+
22+ template <policy::policy_type First, policy::policy_type... Rest>
23+ struct count_concurrency_policies <First, Rest...> {
24+ static constexpr bool is_match =
25+ policy::traits<First>::kind == policy::category::concurrency;
26+ static constexpr std::size_t value =
27+ count_concurrency_policies<Rest...>::value + (is_match ? 1u : 0u );
28+ };
29+
30+ template <policy::policy_type... Policies> struct resolve_concurrency_policy ;
31+
32+ template <> struct resolve_concurrency_policy <> {
33+ using type = policy::defaults::concurrency;
34+ };
35+
36+ template <policy::policy_type First, policy::policy_type... Rest>
37+ struct resolve_concurrency_policy <First, Rest...> {
38+ using type = std::conditional_t <
39+ policy::traits<First>::kind == policy::category::concurrency, First,
40+ typename resolve_concurrency_policy<Rest...>::type>;
41+ };
42+
43+ template <policy::policy_type... Policies>
44+ using resolve_concurrency_policy_t =
45+ typename resolve_concurrency_policy<Policies...>::type;
46+
47+ } // namespace details
48+
1249template <underlying_type T, policy::policy_type... Policies> class primitive {
1350public:
1451 using value_type = T;
1552 using policies = std::tuple<Policies...>;
53+ using concurrency_policy = details::resolve_concurrency_policy_t <Policies...>;
54+
55+ static_assert (details::count_concurrency_policies<Policies...>::value <= 1 ,
56+ " Multiple concurrency policies are not allowed" );
57+
1658 constexpr explicit primitive (value_type v) noexcept : value_(v) {}
1759 constexpr value_type &value () noexcept { return value_; }
1860 [[nodiscard]] constexpr value_type const &value () const noexcept { return value_; }
1961 constexpr explicit operator value_type () const noexcept { return value_; }
2062
63+ [[nodiscard]] auto load () const noexcept -> value_type {
64+ using access_handler_t =
65+ policy::concurrency::handler<concurrency_policy, void , value_type,
66+ policy::error::kind>;
67+ static_assert (
68+ policy::concurrency::handler_access_available<concurrency_policy,
69+ value_type>,
70+ " Selected concurrency policy does not provide primitive "
71+ " load/store/CAS support" );
72+ return access_handler_t::load (value_);
73+ }
74+
75+ auto store (value_type desired) noexcept -> void {
76+ using access_handler_t =
77+ policy::concurrency::handler<concurrency_policy, void , value_type,
78+ policy::error::kind>;
79+ static_assert (
80+ policy::concurrency::handler_access_available<concurrency_policy,
81+ value_type>,
82+ " Selected concurrency policy does not provide primitive "
83+ " load/store/CAS support" );
84+ access_handler_t::store (value_, desired);
85+ }
86+
87+ auto compare_exchange (value_type &expected, value_type desired) noexcept
88+ -> bool {
89+ using access_handler_t =
90+ policy::concurrency::handler<concurrency_policy, void , value_type,
91+ policy::error::kind>;
92+ static_assert (
93+ policy::concurrency::handler_access_available<concurrency_policy,
94+ value_type>,
95+ " Selected concurrency policy does not provide primitive "
96+ " load/store/CAS support" );
97+ return access_handler_t::compare_exchange (value_, expected, desired);
98+ }
99+
21100private:
22101 value_type value_;
23102};
0 commit comments