55#include < type_traits>
66#include < vector>
77
8-
98import mcpplibs.primitives;
109
1110using namespace mcpplibs ::primitives;
@@ -87,9 +86,9 @@ TEST(OperationsTest, UncheckedDivisionUsesRawArithmeticWhenValid) {
8786 EXPECT_EQ (result->value (), 25 );
8887}
8988
90- TEST (OperationsTest, AtomicPolicyPathReturnsExpectedValue ) {
89+ TEST (OperationsTest, FencedPolicyPathReturnsExpectedValue ) {
9190 using value_t =
92- primitive<int , policy::value::checked, policy::concurrency::atomic ,
91+ primitive<int , policy::value::checked, policy::concurrency::fenced ,
9392 policy::error::expected>;
9493
9594 auto const lhs = value_t {12 };
@@ -101,9 +100,9 @@ TEST(OperationsTest, AtomicPolicyPathReturnsExpectedValue) {
101100 EXPECT_EQ (result->value (), 42 );
102101}
103102
104- TEST (OperationsTest, AtomicPolicyConcurrentInvocationsRemainConsistent ) {
103+ TEST (OperationsTest, FencedPolicyConcurrentInvocationsRemainConsistent ) {
105104 using value_t =
106- primitive<int , policy::value::checked, policy::concurrency::atomic ,
105+ primitive<int , policy::value::checked, policy::concurrency::fenced ,
107106 policy::error::expected>;
108107
109108 constexpr int kThreadCount = 8 ;
@@ -148,6 +147,55 @@ TEST(OperationsTest, AtomicPolicyConcurrentInvocationsRemainConsistent) {
148147 EXPECT_EQ (mismatch_count.load (std::memory_order_relaxed), 0 );
149148}
150149
150+ TEST (OperationsTest, PrimitiveFencedLoadStoreAndCasWork) {
151+ using value_t =
152+ primitive<int , policy::value::checked, policy::concurrency::fenced,
153+ policy::error::expected>;
154+
155+ auto value = value_t {1 };
156+ EXPECT_EQ (value.load (), 1 );
157+
158+ value.store (4 );
159+ EXPECT_EQ (value.load (), 4 );
160+
161+ auto expected = 4 ;
162+ EXPECT_TRUE (value.compare_exchange (expected, 7 ));
163+ EXPECT_EQ (value.load (), 7 );
164+
165+ expected = 9 ;
166+ EXPECT_FALSE (value.compare_exchange (expected, 11 ));
167+ EXPECT_EQ (expected, 7 );
168+ }
169+
170+ TEST (OperationsTest, PrimitiveFencedCasSupportsConcurrentIncrements) {
171+ using value_t =
172+ primitive<int , policy::value::checked, policy::concurrency::fenced,
173+ policy::error::expected>;
174+
175+ constexpr int kThreadCount = 6 ;
176+ constexpr int kIterationsPerThread = 5000 ;
177+
178+ auto counter = value_t {0 };
179+ std::vector<std::thread> workers;
180+ workers.reserve (kThreadCount );
181+
182+ for (int i = 0 ; i < kThreadCount ; ++i) {
183+ workers.emplace_back ([&]() {
184+ for (int n = 0 ; n < kIterationsPerThread ; ++n) {
185+ auto expected = counter.load ();
186+ while (!counter.compare_exchange (expected, expected + 1 )) {
187+ }
188+ }
189+ });
190+ }
191+
192+ for (auto &worker : workers) {
193+ worker.join ();
194+ }
195+
196+ EXPECT_EQ (counter.load (), kThreadCount * kIterationsPerThread );
197+ }
198+
151199TEST (OperationsTest, StrictTypeRejectsMixedTypesAtCompileTime) {
152200 using lhs_t = primitive<int , policy::value::checked, policy::type::strict,
153201 policy::error::expected>;
0 commit comments