Skip to content

Commit 7dbf90a

Browse files
test: Add unit tests for overload versions of store/compare_exchange of primitive
1 parent 7fd91b8 commit 7dbf90a

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

tests/basic/test_operations.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ concept constructible_from_underlying =
1818
Primitive{u};
1919
};
2020

21+
template <typename Primitive, typename U>
22+
concept storable_from_underlying =
23+
underlying_type<U> && requires(Primitive p, U u) {
24+
p.store(u);
25+
};
26+
27+
template <typename Primitive, typename U>
28+
concept cas_from_underlying =
29+
underlying_type<U> && requires(Primitive p, U expected, U desired) {
30+
{ p.compare_exchange(expected, desired) } -> std::same_as<bool>;
31+
};
32+
2133
TEST(OperationsTest, AddReturnsExpectedPrimitive) {
2234
using lhs_t = primitive<int, policy::value::checked>;
2335
using rhs_t = primitive<int, policy::value::checked>;
@@ -384,6 +396,55 @@ TEST(OperationsTest, TransparentTypePrimitiveConstructorAllowsCrossCategory) {
384396
EXPECT_EQ(value.load(), 42);
385397
}
386398

399+
TEST(OperationsTest, PrimitiveStoreAndCasRejectCrossUnderlyingWithStrictType) {
400+
using strict_t = primitive<int, policy::type::strict, policy::error::expected>;
401+
402+
static_assert(!storable_from_underlying<strict_t, short>);
403+
static_assert(!cas_from_underlying<strict_t, short>);
404+
}
405+
406+
TEST(OperationsTest, PrimitiveStoreAndCasAllowCompatibleSameCategory) {
407+
using compatible_t =
408+
primitive<int, policy::type::compatible, policy::error::expected>;
409+
410+
static_assert(storable_from_underlying<compatible_t, short>);
411+
static_assert(cas_from_underlying<compatible_t, short>);
412+
static_assert(!storable_from_underlying<compatible_t, double>);
413+
static_assert(!cas_from_underlying<compatible_t, double>);
414+
415+
auto value = compatible_t{10};
416+
value.store(static_cast<short>(12));
417+
EXPECT_EQ(value.load(), 12);
418+
419+
short expected = 12;
420+
EXPECT_TRUE(value.compare_exchange(expected, static_cast<short>(20)));
421+
EXPECT_EQ(value.load(), 20);
422+
423+
expected = 11;
424+
EXPECT_FALSE(value.compare_exchange(expected, static_cast<short>(30)));
425+
EXPECT_EQ(expected, 20);
426+
}
427+
428+
TEST(OperationsTest, PrimitiveStoreAndCasAllowTransparentCrossCategory) {
429+
using transparent_t =
430+
primitive<int, policy::type::transparent, policy::error::expected>;
431+
432+
static_assert(storable_from_underlying<transparent_t, double>);
433+
static_assert(cas_from_underlying<transparent_t, double>);
434+
435+
auto value = transparent_t{10};
436+
value.store(42.75);
437+
EXPECT_EQ(value.load(), 42);
438+
439+
double expected = 42.0;
440+
EXPECT_TRUE(value.compare_exchange(expected, 99.5));
441+
EXPECT_EQ(value.load(), 99);
442+
443+
expected = 3.0;
444+
EXPECT_FALSE(value.compare_exchange(expected, 1.0));
445+
EXPECT_EQ(expected, 99.0);
446+
}
447+
387448
TEST(OperationsTest, PrimitiveSpecialMembersSupportCrossUnderlyingWithCompatibleType) {
388449
using dst_t =
389450
primitive<int, policy::type::compatible, policy::error::expected>;

0 commit comments

Comments
 (0)