basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | 2346d85f705b04c4a9d1847a6c49e1cde7f81665 |
parent | 9efe4c77766b9826ff56a95e2e655c319c38a503 |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Wed, 18 Jun 2025 21:45:41 +0200 |
Clamp algorithm, constexpr min and max
A | include/based/algorithms/clamp.hpp | | | ++++++++++++++++++++++++++++++++++++++++++++++ |
M | include/based/algorithms/max.hpp | | | +++ ----------- |
M | include/based/algorithms/min.hpp | | | +++ ----------- |
3 files changed, 52 insertions(+), 22 deletions(-)
diff --git a/ include/based/algorithms/clamp.hpp b/ include/based/algorithms/clamp.hpp
@@ -0,0 +1,46 @@
#pragma once
#include "based/algorithms/max.hpp"
#include "based/algorithms/min.hpp"
#include "based/concepts/is/regular.hpp"
#include "based/concepts/is/same.hpp"
#include "based/concepts/procedure/procedure.hpp"
#include "based/trait/remove/reference.hpp"
#include "based/utility/forward.hpp"
namespace based
{
// clamp a value between low and high
template<
BareRegular T,
BareRegular U,
BareRegular V,
RegularProcedure<bool, T, T> Rel>
requires(BareSameAs<T, U> && BareSameAs<T, V>)
constexpr decltype(auto) clamp(T&& value, U&& low, V&& high, Rel rel)
{
return based::max(
based::forward<U>(low),
based::min(based::forward<V>(high), based::forward<T>(value), rel),
rel
);
}
// clamp a value between low and high
template<BareRegular T, BareRegular U, BareRegular V>
requires(BareSameAs<T, U> && BareSameAs<T, V>)
constexpr decltype(auto) clamp(T&& value, U&& low, V&& high)
{
return based::clamp(
based::forward<T>(value),
based::forward<U>(low),
based::forward<V>(high),
[](const remove_reference_t<T>& llhs, const remove_reference_t<U>& lrhs)
{
return llhs < lrhs;
}
);
}
} // namespace based
diff --git a/ include/based/algorithms/max.hpp b/ include/based/algorithms/max.hpp
@@ -9,18 +9,10 @@
namespace based
{
namespace detail
{
template<typename P, typename Arg>
concept NoninputRelation = RegularProcedure<P, bool, Arg, Arg>;
} // namespace detail
// returns max element, second if equal
template<BareRegular T, BareRegular U, detail::NoninputRelation<T> Rel>
template<BareRegular T, BareRegular U, RegularProcedure<bool, T, T> Rel>
requires BareSameAs<T, U>
decltype(auto) max(T&& lhs, U&& rhs, Rel rel)
constexpr decltype(auto) max(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? based::forward<T>(lhs) : based::forward<U>(rhs);
}
@@ -28,7 +20,7 @@
decltype(auto) max(T&& lhs, U&& rhs, Rel rel)
// returns max element, second if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
decltype(auto) max(T&& lhs, U&& rhs)
constexpr decltype(auto) max(T&& lhs, U&& rhs)
{
return based::max(
based::forward<T>(lhs),
diff --git a/ include/based/algorithms/min.hpp b/ include/based/algorithms/min.hpp
@@ -9,17 +9,9 @@
namespace based
{
namespace detail
{
template<typename P, typename Arg>
concept NoninputRelation = RegularProcedure<P, bool, Arg, Arg>;
} // namespace detail
template<BareRegular T, BareRegular U, detail::NoninputRelation<T> Rel>
template<BareRegular T, BareRegular U, RegularProcedure<bool, T, T> Rel>
requires BareSameAs<T, U>
decltype(auto) min(T&& lhs, U&& rhs, Rel rel)
constexpr decltype(auto) min(T&& lhs, U&& rhs, Rel rel)
{
return rel(rhs, lhs) ? based::forward<U>(rhs) : based::forward<T>(lhs);
}
@@ -27,7 +19,7 @@
decltype(auto) min(T&& lhs, U&& rhs, Rel rel)
// returns min element, first if equal
template<BareRegular T, BareRegular U>
requires BareSameAs<T, U>
decltype(auto) min(T&& lhs, U&& rhs)
constexpr decltype(auto) min(T&& lhs, U&& rhs)
{
return based::min(
based::forward<T>(lhs),