Skip to content

Commit 14dae86

Browse files
Merge pull request #23 from mcpplibs/feat-add-compare-operator
Feat add compare operator
2 parents 3f19396 + 4041ddd commit 14dae86

File tree

4 files changed

+653
-0
lines changed

4 files changed

+653
-0
lines changed

src/operations/impl.cppm

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ struct BitwiseXor {};
2727
struct Equal {};
2828
struct NotEqual {};
2929
struct ThreeWayCompare {};
30+
struct LessThan {};
31+
struct GreaterThan {};
32+
struct LessThanOrEqual {};
33+
struct GreaterThanOrEqual {};
3034

3135
template <> struct traits<Increment> {
3236
using op_tag = Increment;
@@ -172,4 +176,36 @@ template <> struct traits<ThreeWayCompare> {
172176
static constexpr auto capability_mask = capability::comparison;
173177
};
174178

179+
template <> struct traits<LessThan> {
180+
using op_tag = LessThan;
181+
182+
static constexpr bool enabled = true;
183+
static constexpr auto arity = dimension::binary;
184+
static constexpr auto capability_mask = capability::comparison;
185+
};
186+
187+
template <> struct traits<GreaterThan> {
188+
using op_tag = GreaterThan;
189+
190+
static constexpr bool enabled = true;
191+
static constexpr auto arity = dimension::binary;
192+
static constexpr auto capability_mask = capability::comparison;
193+
};
194+
195+
template <> struct traits<LessThanOrEqual> {
196+
using op_tag = LessThanOrEqual;
197+
198+
static constexpr bool enabled = true;
199+
static constexpr auto arity = dimension::binary;
200+
static constexpr auto capability_mask = capability::comparison;
201+
};
202+
203+
template <> struct traits<GreaterThanOrEqual> {
204+
using op_tag = GreaterThanOrEqual;
205+
206+
static constexpr bool enabled = true;
207+
static constexpr auto arity = dimension::binary;
208+
static constexpr auto capability_mask = capability::comparison;
209+
};
210+
175211
} // namespace mcpplibs::primitives::operations

src/operations/invoker.cppm

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
490604
template <typename T>
491605
constexpr 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+
14471681
template <typename OpTag, typename ValuePolicy, typename CommonRep>
14481682
concept op_binding_available = requires {
14491683
requires operation<OpTag>;

0 commit comments

Comments
 (0)