Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/operations/impl.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ struct BitwiseXor {};
struct Equal {};
struct NotEqual {};
struct ThreeWayCompare {};
struct LessThan {};
struct GreaterThan {};
struct LessThanOrEqual {};
struct GreaterThanOrEqual {};

template <> struct traits<Increment> {
using op_tag = Increment;
Expand Down Expand Up @@ -172,4 +176,36 @@ template <> struct traits<ThreeWayCompare> {
static constexpr auto capability_mask = capability::comparison;
};

template <> struct traits<LessThan> {
using op_tag = LessThan;

static constexpr bool enabled = true;
static constexpr auto arity = dimension::binary;
static constexpr auto capability_mask = capability::comparison;
};

template <> struct traits<GreaterThan> {
using op_tag = GreaterThan;

static constexpr bool enabled = true;
static constexpr auto arity = dimension::binary;
static constexpr auto capability_mask = capability::comparison;
};

template <> struct traits<LessThanOrEqual> {
using op_tag = LessThanOrEqual;

static constexpr bool enabled = true;
static constexpr auto arity = dimension::binary;
static constexpr auto capability_mask = capability::comparison;
};

template <> struct traits<GreaterThanOrEqual> {
using op_tag = GreaterThanOrEqual;

static constexpr bool enabled = true;
static constexpr auto arity = dimension::binary;
static constexpr auto capability_mask = capability::comparison;
};

} // namespace mcpplibs::primitives::operations
234 changes: 234 additions & 0 deletions src/operations/invoker.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,120 @@ constexpr auto compare_three_way(T lhs, T rhs) -> policy::value::decision<T> {
"common type");
}

template <typename T>
constexpr auto compare_less_than(T lhs, T rhs) -> policy::value::decision<T> {
policy::value::decision<T> out{};
if constexpr (!(requires { T{0}; T{1}; })) {
return make_error<T>(
policy::error::kind::unspecified,
"less than comparison result is not representable for common type");
}

if constexpr (std::same_as<std::remove_cv_t<T>, bool>) {
return make_error<T>(
policy::error::kind::unspecified,
"less than comparison is not representable for bool common type");
} else if constexpr (requires { lhs < rhs; }) {
out.has_value = true;
out.value = T{lhs < rhs};
return out;
} else if constexpr (requires { lhs <=> rhs; }) {
auto const cmp = lhs <=> rhs;
out.has_value = true;
out.value = T{cmp < 0};
return out;
}

return make_error<T>(policy::error::kind::unspecified,
"less than not supported for negotiated common type");
}

template <typename T>
constexpr auto compare_greater_than(T lhs, T rhs) -> policy::value::decision<T> {
policy::value::decision<T> out{};
if constexpr (!(requires { T{0}; T{1}; })) {
return make_error<T>(
policy::error::kind::unspecified,
"greater than comparison result is not representable for common type");
}

if constexpr (std::same_as<std::remove_cv_t<T>, bool>) {
return make_error<T>(
policy::error::kind::unspecified,
"greater than comparison is not representable for bool common type");
} else if constexpr (requires { lhs > rhs; }) {
out.has_value = true;
out.value = T{lhs > rhs};
return out;
} else if constexpr (requires { lhs <=> rhs; }) {
auto const cmp = lhs <=> rhs;
out.has_value = true;
out.value = T{cmp > 0};
return out;
}

return make_error<T>(policy::error::kind::unspecified,
"greater than not supported for negotiated common type");
}

template <typename T>
constexpr auto compare_less_than_or_equal(T lhs, T rhs)
-> policy::value::decision<T> {
policy::value::decision<T> out{};
if constexpr (!(requires { T{0}; T{1}; })) {
return make_error<T>(
policy::error::kind::unspecified,
"less than or equal comparison result is not representable for common type");
}

if constexpr (std::same_as<std::remove_cv_t<T>, bool>) {
return make_error<T>(
policy::error::kind::unspecified,
"less than or equal comparison is not representable for bool common type");
} else if constexpr (requires { lhs <= rhs; }) {
out.has_value = true;
out.value = T{lhs <= rhs};
return out;
} else if constexpr (requires { lhs <=> rhs; }) {
auto const cmp = lhs <=> rhs;
out.has_value = true;
out.value = T{cmp <= 0};
return out;
}

return make_error<T>(policy::error::kind::unspecified,
"less than or equal not supported for negotiated common type");
}

template <typename T>
constexpr auto compare_greater_than_or_equal(T lhs, T rhs)
-> policy::value::decision<T> {
policy::value::decision<T> out{};
if constexpr (!(requires { T{0}; T{1}; })) {
return make_error<T>(
policy::error::kind::unspecified,
"greater than or equal comparison result is not representable for common type");
}

if constexpr (std::same_as<std::remove_cv_t<T>, bool>) {
return make_error<T>(
policy::error::kind::unspecified,
"greater than or equal comparison is not representable for bool common type");
} else if constexpr (requires { lhs >= rhs; }) {
out.has_value = true;
out.value = T{lhs >= rhs};
return out;
} else if constexpr (requires { lhs <=> rhs; }) {
auto const cmp = lhs <=> rhs;
out.has_value = true;
out.value = T{cmp >= 0};
return out;
}

return make_error<T>(policy::error::kind::unspecified,
"greater than or equal not supported for negotiated common type");
}

template <typename T>
constexpr auto unchecked_add(T lhs, T rhs) -> policy::value::decision<T> {
policy::value::decision<T> out{};
Expand Down Expand Up @@ -1444,6 +1558,126 @@ struct op_binding<ThreeWayCompare, policy::value::saturating, CommonRep> {
}
};

template <typename CommonRep>
struct op_binding<LessThan, policy::value::checked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<LessThan, policy::value::unchecked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<LessThan, policy::value::saturating, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThan, policy::value::checked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThan, policy::value::unchecked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThan, policy::value::saturating, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<LessThanOrEqual, policy::value::checked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than_or_equal(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<LessThanOrEqual, policy::value::unchecked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than_or_equal(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<LessThanOrEqual, policy::value::saturating, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_less_than_or_equal(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThanOrEqual, policy::value::checked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than_or_equal(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThanOrEqual, policy::value::unchecked, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than_or_equal(lhs, rhs);
}
};

template <typename CommonRep>
struct op_binding<GreaterThanOrEqual, policy::value::saturating, CommonRep> {
static constexpr bool enabled = true;

static constexpr auto apply(CommonRep lhs, CommonRep rhs)
-> policy::value::decision<CommonRep> {
return details::compare_greater_than_or_equal(lhs, rhs);
}
};

template <typename OpTag, typename ValuePolicy, typename CommonRep>
concept op_binding_available = requires {
requires operation<OpTag>;
Expand Down
Loading
Loading