Euphoria
range.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 
5 #include <type_traits>
6 
7 
8 #include "base/angle.h"
9 #include "assert/assert.h"
10 #include "base/cint.h"
11 
12 namespace eu
13 {
14  template <typename T>
15  struct Range
16  {
19 
20  constexpr Range(T min, T max) : lower_bound(min), upper_bound(max)
21  {
23  }
24 
25  explicit Range(T max) : lower_bound(0), upper_bound(max)
26  {
28  }
29 
30  [[nodiscard]] T
31  get_distance() const
32  {
33  return upper_bound - lower_bound;
34  }
35  };
36 
37 
38  template <typename T>
40  {
41  return {min, max};
42  }
43 
44  template <typename T>
46  {
47  return Range<T>(max);
48  }
49 
50  template <typename T>
51  Range<int> make_range(const std::vector<T>& v)
52  {
53  ASSERT(!v.empty());
54  return make_range<int>(c_sizet_to_int(v.size()) - 1);
55  }
56 
57  constexpr Range<float> r01 = { 0.0f, 1.0f};
58  constexpr Range<float> r11 = { -1.0f, 1.0};
59 
60  float from_01f(float lower_bound, float upper_bound, float value);
61 
62  template <typename T>
63  T from_01(const Range<T>& range, float value)
64  {
65  const float r = from_01f
66  (
67  static_cast<float>(range.lower_bound),
68  static_cast<float>(range.upper_bound),
69  value
70  );
71 
72  if constexpr (std::is_unsigned<T>::value)
73  {
74  ASSERT(r >= 0.0f);
75  }
76 
77  return static_cast<T>(r);
78  }
79 
80  template <>
81  float from_01(const Range<float>& range, float value);
82 
83  template <typename T>
84  float to01(const Range<T>& range, T value)
85  {
86  return (value - range.lower_bound)
87  / (range.upper_bound - range.lower_bound);
88  }
89 
90  // inclusive
91  template <typename T>
92  T get360_angular(const Range<T>& range, float value)
93  {
94  const float half_difference
95  = (range.upper_bound - range.lower_bound) / 2.0f;
96  return range.lower_bound + half_difference
97  - half_difference * cos(Angle::from_percent_of_360(value));
98  }
99 
100  template <typename T, typename F>
101  T remap_to(const Range<F>& from, const Range<T>& to, F value)
102  {
103  return from_01(to, to01(from, value));
104  }
105 
106  // includsive, both min and max are included
107  template <typename T>
108  bool is_within(const Range<T>& range, T value)
109  {
110  return value >= range.lower_bound && value <= range.upper_bound;
111  }
112 
113  // inclusive, both min and max are included
114  template <typename T>
115  T keep_within(const Range<T>& range, T value)
116  {
117  if(value > range.upper_bound)
118  {
119  return range.upper_bound;
120  }
121  if(value < range.lower_bound)
122  {
123  return range.lower_bound;
124  }
125 
126  return value;
127  }
128 
129  template <typename T>
130  T wrap(const Range<T>& range, T value)
131  {
132  const T diff = range.upper_bound - range.lower_bound;
133  ASSERT(diff > 0);
134  T wrapped = value - range.lower_bound;
135  while(wrapped < 0)
136  {
137  wrapped += diff;
138  }
139  while(wrapped > diff)
140  {
141  wrapped -= diff;
142  }
143  return range.lower_bound + wrapped;
144  }
145 
146 }
147 
#define ASSERTX(x,...)
Definition: assert.h:48
#define ASSERT(x)
Definition: assert.h:29
Definition: assert.h:90
T keep_within(const Range< T > &range, T value)
Definition: range.h:115
int c_sizet_to_int(size_t t)
Definition: cint.cc:11
float from_01f(float lower_bound, float upper_bound, float value)
Definition: range.cc:6
float to01(const Range< T > &range, T value)
Definition: range.h:84
Range< T > make_range(T min, T max)
Definition: range.h:39
T remap_to(const Range< F > &from, const Range< T > &to, F value)
Definition: range.h:101
T wrap(const Range< T > &range, T value)
Definition: range.h:130
float from_01(const Range< float > &range, float value)
Definition: range.cc:13
float cos(const Angle &ang)
Definition: angle.cc:68
size2f min(const size2f lhs, const size2f rhs)
Definition: size2.cc:140
constexpr Range< float > r01
Definition: range.h:57
bool is_within(const Range< T > &range, T value)
Definition: range.h:108
size2f max(const size2f lhs, const size2f rhs)
Definition: size2.cc:149
constexpr Range< float > r11
Definition: range.h:58
T get360_angular(const Range< T > &range, float value)
Definition: range.h:92
constexpr float from_percent_of_360() const
Definition: angle.h:56
Range(T max)
Definition: range.h:25
T upper_bound
Definition: range.h:18
constexpr Range(T min, T max)
Definition: range.h:20
T get_distance() const
Definition: range.h:31
T lower_bound
Definition: range.h:17