emlabcpp
modern opinionated embedded C++ library
bounded.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./concepts.h"
27 
28 #include <optional>
29 #include <type_traits>
30 
31 namespace emlabcpp
32 {
33 
42 template < typename T, T MinVal, T MaxVal >
43 class bounded
44 {
45  static_assert( MinVal <= MaxVal, "MinVal must be less than or equal to MaxVal" );
46  T val_;
47 
48  constexpr explicit bounded( T val )
49  : val_( val )
50  {
51  }
52 
53 public:
54  static constexpr T min_val = MinVal;
55  static constexpr T max_val = MaxVal;
56  static constexpr T interval_range = static_cast< T >( 1 ) + max_val - min_val;
57  static constexpr bool has_single_element = MinVal == MaxVal;
58 
60  template < typename U, U OtherMin, U OtherMax >
62  std::is_integral_v< U > && std::is_integral_v< T > && min_val <= OtherMin &&
63  OtherMax <= max_val )
64  constexpr bounded( bounded< U, OtherMin, OtherMax > other )
65  : val_( static_cast< T >( *other ) )
66  {
67  }
68 
71  template < T Val >
72  static constexpr bounded get()
73  {
74  static_assert( min_val <= Val && Val <= max_val, "Value out of bounds" );
75  return bounded{ Val };
76  }
77 
80  template < typename U >
81  static std::optional< bounded< T, min_val, max_val > > make( U val )
82  {
83  if ( static_cast< T >( val ) < min_val )
84  return {};
85  if ( static_cast< T >( val ) > max_val )
86  return {};
87  return bounded{ static_cast< T >( val ) };
88  }
89 
91  {
92  return bounded{ min_val };
93  }
94 
96  {
97  return bounded{ max_val };
98  }
99 
100  constexpr bounded()
101  : val_( min_val )
102  {
103  }
104 
105  constexpr T operator*() const
106  {
107  return val_;
108  }
109 
110  explicit operator T() const
111  {
112  return val_;
113  }
114 
116  void rotate_right( T step )
117  {
118  val_ = min_val + ( interval_range + ( val_ + step - min_val ) % interval_range ) %
120  }
121 
123  void rotate_left( T step )
124  {
125  val_ = min_val + ( interval_range + ( val_ - step - min_val ) % interval_range ) %
127  }
128 
129  friend constexpr auto operator<=>( bounded const&, bounded const& ) = default;
130 
131  template < typename U >
132  friend constexpr auto operator<=>( bounded const& b, U const& val )
133  {
134  return *b <=> val;
135  }
136 
138  template < T FromOther, T ToOther >
141  {
143  }
144 
145  template < typename U, U FromOther, U ToOther >
146  friend class bounded;
147 };
148 
150 template < std::size_t N >
152 
153 namespace detail
154 {
155  template < typename T, T MinVal, T MaxVal >
157  {
158  return true;
159  }
160 } // namespace detail
161 
163 template < typename T >
165 
166 #ifdef EMLABCPP_USE_OSTREAM
167 template < typename T, T MinVal, T MaxVal >
168 std::ostream& operator<<( std::ostream& os, bounded< T, MinVal, MaxVal > const& b )
169 {
170  return os << *b;
171 }
172 #endif
173 
174 } // namespace emlabcpp
The bounded class represents a wrapper over type T constrained between MinVal and MaxVal as compile-t...
Definition: bounded.h:44
static bounded< T, min_val, max_val > min()
Definition: bounded.h:90
static bounded< T, min_val, max_val > max()
Definition: bounded.h:95
void rotate_right(T step)
Rotation to the right increases the internal value by step modulo the range it is in.
Definition: bounded.h:116
static constexpr bool has_single_element
Definition: bounded.h:57
constexpr friend auto operator<=>(bounded const &, bounded const &)=default
static std::optional< bounded< T, min_val, max_val > > make(U val)
Creates an optional bounded value if the input value is within the allowed range.
Definition: bounded.h:81
constexpr T operator*() const
Definition: bounded.h:105
requires(std::is_integral_v< U > &&std::is_integral_v< T > &&min_val<=OtherMin &&OtherMax<=max_val) const expr bounded(bounded< U
Constructor that allows conversion from another bounded type with compatible bounds.
static constexpr T min_val
Definition: bounded.h:54
OtherMin
Definition: bounded.h:64
constexpr friend auto operator<=>(bounded const &b, U const &val)
Definition: bounded.h:132
void rotate_left(T step)
Rotation to the left decreases the internal value by step modulo the range it is in.
Definition: bounded.h:123
static constexpr T max_val
Definition: bounded.h:55
OtherMax other
Definition: bounded.h:74
constexpr bounded< T, MinVal+FromOther, MaxVal+ToOther > operator+(bounded< T, FromOther, ToOther > const &other) const
Sum of two bounded types of same base type is bounded within appropiate ranges.
Definition: bounded.h:140
constexpr bounded()
Definition: bounded.h:100
return bounded
Definition: bounded.h:75
static constexpr T interval_range
Definition: bounded.h:56
constexpr bool bounded_derived_test(bounded< T, MinVal, MaxVal > const &)
Definition: bounded.h:156
MIT License.
Definition: impl.h:31
constexpr auto bounded_constant
Simple type alias for bounded index constants.
Definition: bounded.h:151
requires(!range_container< Container >) const expr std
Returns index of an element in tuple 't', for which call to predicate f(x) holds true,...
Definition: algorithm.h:127
concept bounded_derived
Concept that matchestype deriving from bounded.
Definition: bounded.h:164
std::ostream & operator<<(std::ostream &os, string_buffer< N > const &sb)
Definition: string_buffer.h:112