<range.h> util::range: Added out-of-place clamp `T clamped(const)` and `T clamped(&&)`.

Fortune for cpprng's current commit: Future blessing − 末吉
lib
Avril 3 years ago
parent a9bc96294a
commit 800e0ad13b
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -59,7 +59,8 @@ namespace util {
: value <= end); : value <= end);
} }
constexpr inline void clamp(T& value) const // Clamp `value` in-place to be inside this range.
constexpr inline T& clamp(T& value) const
{ {
if constexpr(Bounds.low == bound::Exclusive) { if constexpr(Bounds.low == bound::Exclusive) {
if (value <= start) value = start + 1; if (value <= start) value = start + 1;
@ -67,11 +68,25 @@ namespace util {
if constexpr(Bounds.high == bound::Exclusive) { if constexpr(Bounds.high == bound::Exclusive) {
if (value >= end) value = end - 1; if (value >= end) value = end - 1;
} else if (value > end) value = end; } else if (value > end) value = end;
return value;
}
// Clamp to a new value
constexpr inline T clamped(T&& value) const
{
clamp(value);
return value;
}
// Clamp value out-of-place
constexpr inline T clamped(const T& value) const
{
T res = value;
clamp(res);
return res;
} }
// Scale the `value` from this range to another one (of a compatable type). // Scale the `value` from this range to another one (of a compatable type).
template<typename U> template<typename U>
constexpr inline auto scale(const range<U>& to, T value) constexpr inline auto scale(const range<U>& to, T value) const
{ {
clamp(value); clamp(value);
const auto diff = length(value); const auto diff = length(value);
@ -80,97 +95,8 @@ namespace util {
return to.start + diff2; return to.start + diff2;
} }
constexpr inline auto scale(const range<T>& to, T value) { return scale<T>(to, value); } constexpr inline auto scale(const range<T>& to, T value) const { return scale<T>(to, value); }
T start, end; T start, end;
}; };
} }
// -- old
#if 0
namespace util{
enum class bound
{
Inclusive,
Exclusive,
};
template<typename T> struct range;
using bounds = range<bound>;
constexpr static inline const bounds default_bounds();
template<typename T>
struct range final
{
using type = T;
//constexpr inline range(T start, T end) : start(start), end(end){}
constexpr inline range(T&& start, T&& end) : start(std::move(start)), end(std::move(end)){}
constexpr inline range(const T& start, const T& end) : start(start), end(end){}
constexpr inline range(range<T>&& move) : start(std::move(move.start)), end(std::move(move.end)) {}
constexpr inline range(const range<T>& copy) : start(copy.start), end(copy.end){}
constexpr inline ~range() {}
constexpr inline auto length() const { return end-start; }
constexpr inline auto length(const T& from) const { return from - start; }
constexpr inline bool negative() const { return length() < 0; }
constexpr inline range<T>& normalise() {
if(negative()) std::swap(start, end);
return *this;
}
template<usize I>
requires (I < 2)
constexpr inline T& get() { return I ? end : start; }
template<usize I>
requires (I < 2)
constexpr inline const T& get() const { return I ? end : start; }
template<bounds Bounds = default_bounds()>
constexpr inline bool contains(const T& value) const
{
return (Bounds.get<0>() == bound::Exclusive
? value > start
: value >= start) &&
(Bounds.get<1>() == bound::Exclusive
? value < end
: value <= end);
}
template<bounds Bounds = default_bounds()>
constexpr inline void clamp(T& value) const
{
if constexpr(Bounds.get<0>() == bound::Exclusive) {
if (value <= start) value = start + 1;
} else if (value < start) value = start;
if constexpr(Bounds.get<1>() == bound::Exclusive) {
if (value >= end) value = end - 1;
} else if (value > end) value = end;
}
// Scale the `value` from this range to another one (of a compatable type).
template<bounds Bounds = default_bounds()>
constexpr inline auto scale(const range<auto>& to, T value)
{
clamp<Bounds>(value);
const auto diff = length(value);
const f64 fract = f64(diff) / f64(length());
const auto diff2 = decltype(to)::type(fract * f64(to.length()));
return to.start + diff2;
}
template<bounds Bounds>
constexpr inline auto scale(const range<T>& to, T value);
T start, end;
};
constexpr static inline const bounds default_bounds() { return { bound::Inclusive, bound::Exclusive }; }
}
#endif

Loading…
Cancel
Save