diff --git a/include/range.h b/include/range.h index 96476bc..f003589 100644 --- a/include/range.h +++ b/include/range.h @@ -1,10 +1,94 @@ #pragma once #include -#include #include +namespace util { + enum class bound + { + Inclusive = 0, + Exclusive + }; + + struct bounds + { + bound low, high; + }; + constexpr inline const bounds default_bounds { bound::Inclusive, bound::Exclusive }; + + template + struct range + { + constexpr static inline const bounds Bounds = B; + 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&& move) : start(std::move(move.start)), end(std::move(move.end)) {} + constexpr inline range(const range& 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& normalise() { + if(negative()) std::swap(start, end); + return *this; + } + + template + requires (I < 2) + constexpr inline T& get() { return I ? end : start; } + template + requires (I < 2) + constexpr inline const T& get() const { return I ? end : start; } + + constexpr inline bool contains(const T& value) const + { + return (Bounds.low == bound::Exclusive + ? value > start + : value >= start) && + (Bounds.high == bound::Exclusive + ? value < end + : value <= end); + } + + constexpr inline void clamp(T& value) const + { + if constexpr(Bounds.low == bound::Exclusive) { + if (value <= start) value = start + 1; + } else if (value < start) value = start; + if constexpr(Bounds.high == 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 + constexpr inline auto scale(const range& to, T value) + { + clamp(value); + const auto diff = length(value); + const f64 fract = f64(diff) / f64(length()); + const auto diff2 = typename range::type(fract * f64(to.length())); + + return to.start + diff2; + } + constexpr inline auto scale(const range& to, T value) { return scale(to, value); } + + T start, end; + }; +} + +// -- old +#if 0 + namespace util{ enum class bound { @@ -89,3 +173,4 @@ struct range final constexpr static inline const bounds default_bounds() { return { bound::Inclusive, bound::Exclusive }; } } +#endif diff --git a/src/rng.cpp b/src/rng.cpp index 24356ae..967bcd8 100644 --- a/src/rng.cpp +++ b/src/rng.cpp @@ -53,5 +53,7 @@ N_INTS void __() { util::range test(-10, 20); - test.scale({ 100, 200 }, 5); + util::range test2(-1000, 2000); + test.scale(test2, 5); + }