@@ -784,6 +784,120 @@ TEST(OperationsTest, OperatorPlusDelegatesToDispatcher) {
784784 EXPECT_EQ (result->value (), 15 );
785785}
786786
787+ TEST (OperationsTest, UnaryOperatorsDelegateToDispatcher) {
788+ using namespace mcpplibs ::primitives::operators;
789+ using value_t =
790+ primitive<int , policy::value::checked, policy::error::expected>;
791+
792+ auto value = value_t {10 };
793+
794+ auto const inc = ++value;
795+ ASSERT_TRUE (inc.has_value ());
796+ EXPECT_EQ (inc->value (), 11 );
797+ EXPECT_EQ (value.load (), 11 );
798+
799+ auto const dec = --value;
800+ ASSERT_TRUE (dec.has_value ());
801+ EXPECT_EQ (dec->value (), 10 );
802+ EXPECT_EQ (value.load (), 10 );
803+
804+ auto const post_inc = value++;
805+ ASSERT_TRUE (post_inc.has_value ());
806+ EXPECT_EQ (post_inc->value (), 10 );
807+ EXPECT_EQ (value.load (), 11 );
808+
809+ auto const post_dec = value--;
810+ ASSERT_TRUE (post_dec.has_value ());
811+ EXPECT_EQ (post_dec->value (), 11 );
812+ EXPECT_EQ (value.load (), 10 );
813+
814+ auto const pos = +value;
815+ auto const neg = -value;
816+ auto const inv = ~value;
817+
818+ ASSERT_TRUE (pos.has_value ());
819+ ASSERT_TRUE (neg.has_value ());
820+ ASSERT_TRUE (inv.has_value ());
821+ EXPECT_EQ (pos->value (), 10 );
822+ EXPECT_EQ (neg->value (), -10 );
823+ EXPECT_EQ (inv->value (), ~10 );
824+ }
825+
826+ TEST (OperationsTest, NewBinaryOperatorsDelegateToDispatcher) {
827+ using namespace mcpplibs ::primitives::operators;
828+ using value_t =
829+ primitive<int , policy::value::checked, policy::error::expected>;
830+
831+ auto const lhs = value_t {12 };
832+ auto const rhs = value_t {5 };
833+
834+ auto const mod = lhs % rhs;
835+ auto const shl = rhs << value_t {1 };
836+ auto const shr = lhs >> value_t {2 };
837+ auto const bit_and = lhs & value_t {10 };
838+ auto const bit_or = lhs | value_t {10 };
839+ auto const bit_xor = lhs ^ value_t {10 };
840+
841+ ASSERT_TRUE (mod.has_value ());
842+ ASSERT_TRUE (shl.has_value ());
843+ ASSERT_TRUE (shr.has_value ());
844+ ASSERT_TRUE (bit_and.has_value ());
845+ ASSERT_TRUE (bit_or.has_value ());
846+ ASSERT_TRUE (bit_xor.has_value ());
847+ EXPECT_EQ (mod->value (), 2 );
848+ EXPECT_EQ (shl->value (), 10 );
849+ EXPECT_EQ (shr->value (), 3 );
850+ EXPECT_EQ (bit_and->value (), 8 );
851+ EXPECT_EQ (bit_or->value (), 14 );
852+ EXPECT_EQ (bit_xor->value (), 6 );
853+ }
854+
855+ TEST (OperationsTest, NewCompoundAssignmentOperatorsMutateLhsOnSuccess) {
856+ using namespace mcpplibs ::primitives::operators;
857+ using value_t =
858+ primitive<int , policy::value::checked, policy::error::expected>;
859+
860+ auto value = value_t {12 };
861+
862+ auto mod = (value %= value_t {5 });
863+ ASSERT_TRUE (mod.has_value ());
864+ EXPECT_EQ (value.load (), 2 );
865+
866+ auto shl = (value <<= value_t {2 });
867+ ASSERT_TRUE (shl.has_value ());
868+ EXPECT_EQ (value.load (), 8 );
869+
870+ auto shr = (value >>= value_t {1 });
871+ ASSERT_TRUE (shr.has_value ());
872+ EXPECT_EQ (value.load (), 4 );
873+
874+ auto bit_and = (value &= value_t {6 });
875+ ASSERT_TRUE (bit_and.has_value ());
876+ EXPECT_EQ (value.load (), 4 );
877+
878+ auto bit_or = (value |= value_t {1 });
879+ ASSERT_TRUE (bit_or.has_value ());
880+ EXPECT_EQ (value.load (), 5 );
881+
882+ auto bit_xor = (value ^= value_t {7 });
883+ ASSERT_TRUE (bit_xor.has_value ());
884+ EXPECT_EQ (value.load (), 2 );
885+ }
886+
887+ TEST (OperationsTest, ModulusAndShiftReportExpectedErrors) {
888+ using value_t =
889+ primitive<int , policy::value::checked, policy::error::expected>;
890+
891+ auto const mod_zero = operations::mod (value_t {7 }, value_t {0 });
892+ ASSERT_FALSE (mod_zero.has_value ());
893+ EXPECT_EQ (mod_zero.error (), policy::error::kind::divide_by_zero);
894+
895+ auto const invalid_shift = operations::shift_left (
896+ value_t {1 }, value_t {std::numeric_limits<int >::digits + 1 });
897+ ASSERT_FALSE (invalid_shift.has_value ());
898+ EXPECT_EQ (invalid_shift.error (), policy::error::kind::domain_error);
899+ }
900+
787901TEST (OperationsTest, ThreeWayCompareReturnsStrongOrderingForIntegers) {
788902 using namespace mcpplibs ::primitives::operators;
789903 using value_t =
0 commit comments