@@ -487,6 +487,120 @@ constexpr auto compare_three_way(T lhs, T rhs) -> policy::value::decision<T> {
487487 " common type" );
488488}
489489
490+ template <typename T>
491+ constexpr auto compare_less_than (T lhs, T rhs) -> policy::value::decision<T> {
492+ policy::value::decision<T> out{};
493+ if constexpr (!(requires { T{0 }; T{1 }; })) {
494+ return make_error<T>(
495+ policy::error::kind::unspecified,
496+ " less than comparison result is not representable for common type" );
497+ }
498+
499+ if constexpr (std::same_as<std::remove_cv_t <T>, bool >) {
500+ return make_error<T>(
501+ policy::error::kind::unspecified,
502+ " less than comparison is not representable for bool common type" );
503+ } else if constexpr (requires { lhs < rhs; }) {
504+ out.has_value = true ;
505+ out.value = T{lhs < rhs};
506+ return out;
507+ } else if constexpr (requires { lhs <=> rhs; }) {
508+ auto const cmp = lhs <=> rhs;
509+ out.has_value = true ;
510+ out.value = T{cmp < 0 };
511+ return out;
512+ }
513+
514+ return make_error<T>(policy::error::kind::unspecified,
515+ " less than not supported for negotiated common type" );
516+ }
517+
518+ template <typename T>
519+ constexpr auto compare_greater_than (T lhs, T rhs) -> policy::value::decision<T> {
520+ policy::value::decision<T> out{};
521+ if constexpr (!(requires { T{0 }; T{1 }; })) {
522+ return make_error<T>(
523+ policy::error::kind::unspecified,
524+ " greater than comparison result is not representable for common type" );
525+ }
526+
527+ if constexpr (std::same_as<std::remove_cv_t <T>, bool >) {
528+ return make_error<T>(
529+ policy::error::kind::unspecified,
530+ " greater than comparison is not representable for bool common type" );
531+ } else if constexpr (requires { lhs > rhs; }) {
532+ out.has_value = true ;
533+ out.value = T{lhs > rhs};
534+ return out;
535+ } else if constexpr (requires { lhs <=> rhs; }) {
536+ auto const cmp = lhs <=> rhs;
537+ out.has_value = true ;
538+ out.value = T{cmp > 0 };
539+ return out;
540+ }
541+
542+ return make_error<T>(policy::error::kind::unspecified,
543+ " greater than not supported for negotiated common type" );
544+ }
545+
546+ template <typename T>
547+ constexpr auto compare_less_than_or_equal (T lhs, T rhs)
548+ -> policy::value::decision<T> {
549+ policy::value::decision<T> out{};
550+ if constexpr (!(requires { T{0 }; T{1 }; })) {
551+ return make_error<T>(
552+ policy::error::kind::unspecified,
553+ " less than or equal comparison result is not representable for common type" );
554+ }
555+
556+ if constexpr (std::same_as<std::remove_cv_t <T>, bool >) {
557+ return make_error<T>(
558+ policy::error::kind::unspecified,
559+ " less than or equal comparison is not representable for bool common type" );
560+ } else if constexpr (requires { lhs <= rhs; }) {
561+ out.has_value = true ;
562+ out.value = T{lhs <= rhs};
563+ return out;
564+ } else if constexpr (requires { lhs <=> rhs; }) {
565+ auto const cmp = lhs <=> rhs;
566+ out.has_value = true ;
567+ out.value = T{cmp <= 0 };
568+ return out;
569+ }
570+
571+ return make_error<T>(policy::error::kind::unspecified,
572+ " less than or equal not supported for negotiated common type" );
573+ }
574+
575+ template <typename T>
576+ constexpr auto compare_greater_than_or_equal (T lhs, T rhs)
577+ -> policy::value::decision<T> {
578+ policy::value::decision<T> out{};
579+ if constexpr (!(requires { T{0 }; T{1 }; })) {
580+ return make_error<T>(
581+ policy::error::kind::unspecified,
582+ " greater than or equal comparison result is not representable for common type" );
583+ }
584+
585+ if constexpr (std::same_as<std::remove_cv_t <T>, bool >) {
586+ return make_error<T>(
587+ policy::error::kind::unspecified,
588+ " greater than or equal comparison is not representable for bool common type" );
589+ } else if constexpr (requires { lhs >= rhs; }) {
590+ out.has_value = true ;
591+ out.value = T{lhs >= rhs};
592+ return out;
593+ } else if constexpr (requires { lhs <=> rhs; }) {
594+ auto const cmp = lhs <=> rhs;
595+ out.has_value = true ;
596+ out.value = T{cmp >= 0 };
597+ return out;
598+ }
599+
600+ return make_error<T>(policy::error::kind::unspecified,
601+ " greater than or equal not supported for negotiated common type" );
602+ }
603+
490604template <typename T>
491605constexpr auto unchecked_add (T lhs, T rhs) -> policy::value::decision<T> {
492606 policy::value::decision<T> out{};
@@ -1444,6 +1558,126 @@ struct op_binding<ThreeWayCompare, policy::value::saturating, CommonRep> {
14441558 }
14451559};
14461560
1561+ template <typename CommonRep>
1562+ struct op_binding <LessThan, policy::value::checked, CommonRep> {
1563+ static constexpr bool enabled = true ;
1564+
1565+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1566+ -> policy::value::decision<CommonRep> {
1567+ return details::compare_less_than (lhs, rhs);
1568+ }
1569+ };
1570+
1571+ template <typename CommonRep>
1572+ struct op_binding <LessThan, policy::value::unchecked, CommonRep> {
1573+ static constexpr bool enabled = true ;
1574+
1575+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1576+ -> policy::value::decision<CommonRep> {
1577+ return details::compare_less_than (lhs, rhs);
1578+ }
1579+ };
1580+
1581+ template <typename CommonRep>
1582+ struct op_binding <LessThan, policy::value::saturating, CommonRep> {
1583+ static constexpr bool enabled = true ;
1584+
1585+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1586+ -> policy::value::decision<CommonRep> {
1587+ return details::compare_less_than (lhs, rhs);
1588+ }
1589+ };
1590+
1591+ template <typename CommonRep>
1592+ struct op_binding <GreaterThan, policy::value::checked, CommonRep> {
1593+ static constexpr bool enabled = true ;
1594+
1595+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1596+ -> policy::value::decision<CommonRep> {
1597+ return details::compare_greater_than (lhs, rhs);
1598+ }
1599+ };
1600+
1601+ template <typename CommonRep>
1602+ struct op_binding <GreaterThan, policy::value::unchecked, CommonRep> {
1603+ static constexpr bool enabled = true ;
1604+
1605+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1606+ -> policy::value::decision<CommonRep> {
1607+ return details::compare_greater_than (lhs, rhs);
1608+ }
1609+ };
1610+
1611+ template <typename CommonRep>
1612+ struct op_binding <GreaterThan, policy::value::saturating, CommonRep> {
1613+ static constexpr bool enabled = true ;
1614+
1615+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1616+ -> policy::value::decision<CommonRep> {
1617+ return details::compare_greater_than (lhs, rhs);
1618+ }
1619+ };
1620+
1621+ template <typename CommonRep>
1622+ struct op_binding <LessThanOrEqual, policy::value::checked, CommonRep> {
1623+ static constexpr bool enabled = true ;
1624+
1625+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1626+ -> policy::value::decision<CommonRep> {
1627+ return details::compare_less_than_or_equal (lhs, rhs);
1628+ }
1629+ };
1630+
1631+ template <typename CommonRep>
1632+ struct op_binding <LessThanOrEqual, policy::value::unchecked, CommonRep> {
1633+ static constexpr bool enabled = true ;
1634+
1635+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1636+ -> policy::value::decision<CommonRep> {
1637+ return details::compare_less_than_or_equal (lhs, rhs);
1638+ }
1639+ };
1640+
1641+ template <typename CommonRep>
1642+ struct op_binding <LessThanOrEqual, policy::value::saturating, CommonRep> {
1643+ static constexpr bool enabled = true ;
1644+
1645+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1646+ -> policy::value::decision<CommonRep> {
1647+ return details::compare_less_than_or_equal (lhs, rhs);
1648+ }
1649+ };
1650+
1651+ template <typename CommonRep>
1652+ struct op_binding <GreaterThanOrEqual, policy::value::checked, CommonRep> {
1653+ static constexpr bool enabled = true ;
1654+
1655+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1656+ -> policy::value::decision<CommonRep> {
1657+ return details::compare_greater_than_or_equal (lhs, rhs);
1658+ }
1659+ };
1660+
1661+ template <typename CommonRep>
1662+ struct op_binding <GreaterThanOrEqual, policy::value::unchecked, CommonRep> {
1663+ static constexpr bool enabled = true ;
1664+
1665+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1666+ -> policy::value::decision<CommonRep> {
1667+ return details::compare_greater_than_or_equal (lhs, rhs);
1668+ }
1669+ };
1670+
1671+ template <typename CommonRep>
1672+ struct op_binding <GreaterThanOrEqual, policy::value::saturating, CommonRep> {
1673+ static constexpr bool enabled = true ;
1674+
1675+ static constexpr auto apply (CommonRep lhs, CommonRep rhs)
1676+ -> policy::value::decision<CommonRep> {
1677+ return details::compare_greater_than_or_equal (lhs, rhs);
1678+ }
1679+ };
1680+
14471681template <typename OpTag, typename ValuePolicy, typename CommonRep>
14481682concept op_binding_available = requires {
14491683 requires operation<OpTag>;
0 commit comments