emlabcpp
modern opinionated embedded C++ library
quantity.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "./concepts.h"
27 
28 #include <cmath>
29 #include <functional>
30 #include <limits>
31 #include <ratio>
32 #include <string>
33 #include <type_traits>
34 
35 #ifdef EMLABCPP_USE_NLOHMANN_JSON
36 #include <nlohmann/json.hpp>
37 #endif
38 
39 namespace emlabcpp
40 {
41 
61 template < typename Derived, typename ValueType = float >
62 class quantity
63 {
64  ValueType value_;
65 
66  [[nodiscard]] Derived& impl()
67  {
68  return static_cast< Derived& >( *this );
69  }
70 
71  [[nodiscard]] Derived const& impl() const
72  {
73  return static_cast< Derived const& >( *this );
74  }
75 
76 public:
77  using value_type = ValueType;
78 
79  constexpr quantity() noexcept
80  : value_( 0 )
81  {
82  }
83 
85  template < typename Value >
86  constexpr explicit quantity( Value val ) noexcept
87  : value_( static_cast< ValueType >( val ) )
88  {
89  }
90 
92  constexpr ValueType operator*() const noexcept
93  {
94  return value_;
95  }
96 
98  constexpr Derived& operator+=( quantity const other ) noexcept
99  {
100  value_ += *other;
101  return impl();
102  }
103 
105  constexpr Derived& operator-=( quantity const other ) noexcept
106  {
107  value_ -= *other;
108  return impl();
109  }
110 
112  constexpr Derived& operator/=( arithmetic auto const val ) noexcept
113  {
114  value_ /= val;
115  return impl();
116  }
117 
119  constexpr Derived& operator*=( arithmetic auto const val ) noexcept
120  {
121  value_ *= val;
122  return impl();
123  }
124 
126  template < typename U >
127  constexpr explicit operator U() const noexcept
128  {
129  return U( value_ );
130  }
131 
132  static std::string get_unit()
133  {
134  return "";
135  }
136 
137  friend constexpr auto operator<=>( quantity const&, quantity const& ) = default;
138 };
139 
140 namespace detail
141 {
142  template < typename Derived, typename ValueType >
144  {
145  return true;
146  }
147 } // namespace detail
148 
150 template < typename T >
152 
159 template < typename Tag, typename ValueType = float >
160 class tagged_quantity : public quantity< tagged_quantity< Tag, ValueType >, ValueType >
161 {
162 public:
163  using tag = Tag;
165 };
166 
168 template < typename Derived, typename ValueType >
169 constexpr Derived
171 {
172  return lhs += rhs;
173 }
174 
176 template < typename Derived, typename ValueType >
177 constexpr Derived
179 {
180  return lhs -= rhs;
181 }
182 
184 template < typename Derived, typename ValueType >
185 constexpr Derived operator-( quantity< Derived, ValueType > const val )
186 {
187  return Derived{ -*val };
188 }
189 
191 template < typename Derived, typename ValueType, arithmetic_like RhValueType >
192 constexpr bool operator<( quantity< Derived, ValueType > const lhs, RhValueType const rhs )
193 {
194  return *lhs < rhs;
195 }
196 
198 template < typename Derived, typename ValueType, arithmetic_like LhValueType >
199 constexpr bool operator<( LhValueType const lhs, quantity< Derived, ValueType > const rhs )
200 {
201  return lhs < *rhs;
202 }
203 
205 template < typename Derived, typename ValueType >
206 constexpr Derived operator*( quantity< Derived, ValueType > q, arithmetic auto const val )
207 {
208  return q *= val;
209 }
210 
212 template < typename Derived, typename ValueType >
213 constexpr Derived operator/( quantity< Derived, ValueType > q, arithmetic auto const val )
214 {
215  return q /= val;
216 }
217 
219 template < typename Derived, typename ValueType >
220 constexpr Derived abs( quantity< Derived, ValueType > const q )
221 {
222  return Derived( std::abs( *q ) );
223 }
224 
226 template < typename Derived, typename ValueType >
227 constexpr auto cos( quantity< Derived, ValueType > const u )
228 {
229  return std::cos( *u );
230 }
231 
233 template < typename Derived, typename ValueType >
234 constexpr auto sin( quantity< Derived, ValueType > const u )
235 {
236  return std::sin( *u );
237 }
238 
240 template < typename Derived, typename ValueType >
241 constexpr Derived
243 {
244  return Derived( std::max( *lh, *rh ) );
245 }
246 
248 template < typename Derived, typename ValueType >
249 constexpr Derived
251 {
252  return Derived( std::min( *lh, *rh ) );
253 }
254 
255 //---------------------------------------------------------------------------
256 
258 template < typename Derived, typename ValueType >
259 constexpr Derived operator*( ValueType const val, quantity< Derived, ValueType > const q )
260 {
261  return q * val;
262 }
263 
265 template < typename Derived, typename ValueType >
266 constexpr ValueType operator/( ValueType const val, quantity< Derived, ValueType > const q )
267 {
268  return val / *q;
269 }
270 
271 #ifdef EMLABCPP_USE_OSTREAM
272 template < typename T, typename ValueType >
273 std::ostream& operator<<( std::ostream& os, quantity< T, ValueType > const& q )
274 {
275  return os << *q << T::get_unit();
276 }
277 #endif
278 
279 } // namespace emlabcpp
280 
283 template < emlabcpp::quantity_derived T >
284 struct std::numeric_limits< T >
285 {
286  using value_type = typename T::value_type;
287 
288  constexpr static T lowest()
289  {
290  return T{ std::numeric_limits< value_type >::lowest() };
291  }
292 
293  constexpr static T min()
294  {
296  }
297 
298  constexpr static T max()
299  {
301  }
302 };
303 
305 template < emlabcpp::quantity_derived T >
306 struct std::hash< T >
307 {
308  std::size_t operator()( T q ) const
309  {
312  std::string const unit = T::get_unit();
313  return std::hash< typename T::value_type >()( *q ) ^
314  std::hash< std::string >()( unit );
315  }
316 };
317 
318 #ifdef EMLABCPP_USE_NLOHMANN_JSON
319 
320 template < emlabcpp::quantity_derived T >
321 struct nlohmann::adl_serializer< T >
322 {
323  static void to_json( nlohmann::json& j, T const q )
324  {
325  if ( T::get_unit().empty() )
326  j = *q;
327  else
328  j[T::get_unit()] = *q;
329  }
330 
331  static T from_json( nlohmann::json const& j )
332  {
333  using value_type = typename T::value_type;
334 
335  if ( T::get_unit().empty() )
336  return T{ j.get< value_type >() };
337  return T{ j[T::get_unit()].template get< value_type >() };
338  }
339 };
340 
341 #endif
Class representing generic quantity.
Definition: quantity.h:63
constexpr friend auto operator<=>(quantity const &, quantity const &)=default
constexpr ValueType operator*() const noexcept
Const reference to the internal value.
Definition: quantity.h:92
constexpr Derived & operator/=(arithmetic auto const val) noexcept
Divides quantity by it's value type.
Definition: quantity.h:112
constexpr Derived & operator-=(quantity const other) noexcept
Subtract other quantity of same Derived and value_type.
Definition: quantity.h:105
constexpr quantity() noexcept
Definition: quantity.h:79
constexpr Derived & operator*=(arithmetic auto const val) noexcept
Multiplies quantity by it's value type.
Definition: quantity.h:119
constexpr quantity(Value val) noexcept
Default constructor used to create a physical quantity from value.
Definition: quantity.h:86
ValueType value_type
Definition: quantity.h:77
constexpr Derived & operator+=(quantity const other) noexcept
Add other quantity of same Derived and value_type.
Definition: quantity.h:98
static std::string get_unit()
Definition: quantity.h:132
Class represents a quantity that uses tags to distinguish quantities instead of inheritance.
Definition: quantity.h:161
Tag tag
Definition: quantity.h:163
constexpr bool quantity_derived_test(quantity< Derived, ValueType > const &)
Definition: quantity.h:143
std::variant< int64_t, float, bool, string_buffer > value_type
Definition: base.h:51
MIT License.
Definition: impl.h:31
constexpr point< N > operator+(point< N > a, vector< N > const &b)
Returns a result of addition a to b, viz += operator.
Definition: point.h:93
constexpr Derived abs(quantity< Derived, ValueType > const q)
Quantity with absolute value of internal value.
Definition: quantity.h:220
constexpr auto sin(quantity< Derived, ValueType > const u)
Returns sinus of the quantity as scalar.
Definition: quantity.h:234
constexpr point< N > operator*(point< N > a, point< N > const &b)
Multiplication of points multiplies each coordinate of A by coordinate of B on same dimension.
Definition: point.h:74
constexpr Derived max(quantity< Derived, ValueType > const lh, quantity< Derived, ValueType > const rh)
Quantity with maximum value of one of the quantities.
Definition: quantity.h:242
concept arithmetic
Definition: concepts.h:65
constexpr Derived abs(vec_point_base< Derived, N > const &a)
Creates absolute version of A - removing signs on all dimensions.
Definition: vec_point_base.h:219
constexpr Derived min(quantity< Derived, ValueType > const lh, quantity< Derived, ValueType > const rh)
Quantity with minimum value of one of the quantities.
Definition: quantity.h:250
concept quantity_derived
Concept satisfies any type T that inherits from any form of quantity<U>.
Definition: quantity.h:151
constexpr auto cos(quantity< Derived, ValueType > const u)
Returns cosinus of the quantity as scalar.
Definition: quantity.h:227
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
constexpr bool operator<(pose const &x, pose const &y)
Definition: pose.h:85
constexpr Derived max(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:229
constexpr vector< N > operator-(point< N > a, point< N > const &b)
Returns a result of subtraction of A from B, viz -= operator.
Definition: point.h:84
constexpr Derived const & min(vec_point_base< Derived, N > const &a, vec_point_base< Derived, N > const &b)
Definition: vec_point_base.h:236
constexpr Derived operator/(vec_point_base< Derived, N > const &a, T s)
Divides each coordinate of A by item 's' of type T, if T satifies std::is_arithmetic.
Definition: vec_point_base.h:170
std::ostream & operator<<(std::ostream &os, string_buffer< N > const &sb)
Definition: string_buffer.h:112
std::size_t operator()(T q) const
Definition: quantity.h:308
constexpr static T max()
Definition: quantity.h:298
constexpr static T min()
Definition: quantity.h:293
constexpr static T lowest()
Definition: quantity.h:288
typename T::value_type value_type
Definition: quantity.h:286