@@ -12,6 +12,12 @@ import mcpplibs.primitives;
1212
1313using namespace mcpplibs ::primitives;
1414
15+ template <typename Primitive, typename U>
16+ concept constructible_from_underlying =
17+ underlying_type<U> && requires (U u) {
18+ Primitive{u};
19+ };
20+
1521TEST (OperationsTest, AddReturnsExpectedPrimitive) {
1622 using lhs_t = primitive<int , policy::value::checked>;
1723 using rhs_t = primitive<int , policy::value::checked>;
@@ -347,6 +353,37 @@ TEST(OperationsTest, StrictTypeAllowsSameTypeAtRuntime) {
347353 EXPECT_EQ (result->value (), 42 );
348354}
349355
356+ TEST (OperationsTest, StrictTypePrimitiveConstructorRejectsCrossUnderlyingType) {
357+ using strict_t = primitive<int , policy::type::strict, policy::error::expected>;
358+
359+ static_assert (constructible_from_underlying<strict_t , int >);
360+ static_assert (!constructible_from_underlying<strict_t , short >);
361+
362+ auto const value = strict_t {42 };
363+ EXPECT_EQ (value.load (), 42 );
364+ }
365+
366+ TEST (OperationsTest, CompatibleTypePrimitiveConstructorAllowsSameCategory) {
367+ using compatible_t =
368+ primitive<int , policy::type::compatible, policy::error::expected>;
369+
370+ static_assert (constructible_from_underlying<compatible_t , short >);
371+ static_assert (!constructible_from_underlying<compatible_t , double >);
372+
373+ auto const value = compatible_t {static_cast <short >(42 )};
374+ EXPECT_EQ (value.load (), 42 );
375+ }
376+
377+ TEST (OperationsTest, TransparentTypePrimitiveConstructorAllowsCrossCategory) {
378+ using transparent_t =
379+ primitive<int , policy::type::transparent, policy::error::expected>;
380+
381+ static_assert (constructible_from_underlying<transparent_t , double >);
382+
383+ auto const value = transparent_t {42.75 };
384+ EXPECT_EQ (value.load (), 42 );
385+ }
386+
350387TEST (OperationsTest, DispatcherMetaTracksResolvedPolicyGroupConsistency) {
351388 using aligned_lhs_t = primitive<int , policy::value::checked,
352389 policy::error::expected>;
0 commit comments