Stratax
Scientific computing containers and operations
Loading...
Searching...
No Matches
Validation.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <limits>
5#include <type_traits>
6
9
14
16
26template<typename Actual, typename Expected>
27void require_type(const char* message)
28{
29 if constexpr (!std::same_as<std::remove_cvref_t<Actual>, std::remove_cvref_t<Expected>>)
30 {
31 throw Exceptions::TypeError(message);
32 }
33}
34
43template<typename T>
44void require_numeric_type(const char* message)
45{
46 if constexpr (!Numeric<T>)
47 {
48 throw Exceptions::TypeError(message);
49 }
50}
51
61template<typename Lhs, typename Rhs>
62requires requires
63{
64 typename Lhs::value_type;
65 typename Rhs::value_type;
66}
67void require_same_value_type(const Lhs&, const Rhs&, const char* message)
68{
70}
71
82inline std::size_t nonnegative_size(long long value, const char* message)
83{
84 if (value < 0)
85 {
86 throw Exceptions::DimensionError(message);
87 }
88
89 return static_cast<std::size_t>(value);
90}
91
102inline std::size_t nonnegative_shape_dimension(long long value, const char* message)
103{
104 if (value < 0)
105 {
106 throw Exceptions::ShapeError(message);
107 }
108
109 return static_cast<std::size_t>(value);
110}
111
122inline std::size_t positive_shape_dimension(long long value, const char* message)
123{
124 if (value <= 0)
125 {
126 throw Exceptions::ShapeError(message);
127 }
128
129 return static_cast<std::size_t>(value);
130}
131
140inline void require_positive_shape_dimension(std::size_t value, const char* message)
141{
142 if (value == 0)
143 {
144 throw Exceptions::ShapeError(message);
145 }
146}
147
158inline std::size_t nonnegative_index(long long value, const char* message)
159{
160 if (value < 0)
161 {
162 throw Exceptions::IndexError(message);
163 }
164
165 return static_cast<std::size_t>(value);
166}
167
177inline void require_rank(std::size_t actual, std::size_t expected, const char* message)
178{
179 if (actual != expected)
180 {
181 throw Exceptions::DimensionError(message);
182 }
183}
184
196template<typename Ranked>
197requires requires(const Ranked& object)
198{
199 object.rank();
200}
201const Ranked& require_rank(const Ranked& object, std::size_t expected, const char* message)
202{
203 require_rank(object.rank(), expected, message);
204 return object;
205}
206
216inline void require_index(std::size_t index, std::size_t size, const char* message)
217{
218 if (index >= size)
219 {
220 throw Exceptions::IndexError(message);
221 }
222}
223
235inline void require_at_most(std::size_t value, std::size_t upper, const char* message)
236{
237 if (value > upper)
238 {
239 throw Exceptions::IndexError(message);
240 }
241}
242
254inline std::size_t checked_multiply(
255 std::size_t lhs,
256 std::size_t rhs,
257 const char* message)
258{
259 if (rhs != 0 && lhs > std::numeric_limits<std::size_t>::max() / rhs)
260 {
261 throw Exceptions::DimensionError(message);
262 }
263
264 return lhs * rhs;
265}
266
278inline std::size_t checked_add(
279 std::size_t lhs,
280 std::size_t rhs,
281 const char* message)
282{
283 if (lhs > std::numeric_limits<std::size_t>::max() - rhs)
284 {
285 throw Exceptions::DimensionError(message);
286 }
287
288 return lhs + rhs;
289}
290
299template<typename Lhs, typename Rhs>
300[[nodiscard]] bool same_shape(const Lhs& lhs, const Rhs& rhs)
301{
302 return lhs.size() == rhs.size() && lhs.shape() == rhs.shape();
303}
304
314template<typename Lhs, typename Rhs>
315void require_same_shape(const Lhs& lhs, const Rhs& rhs, const char* message)
316{
317 if (!same_shape(lhs, rhs))
318 {
319 throw Exceptions::ShapeError(message);
320 }
321}
322
332inline void require_equal_size(std::size_t lhs, std::size_t rhs, const char* message)
333{
334 if (lhs != rhs)
335 {
336 throw Exceptions::ShapeError(message);
337 }
338}
339
340}
Signals an invalid dimension count or dimension arithmetic failure.
Signals an invalid index access.
Signals an invalid or incompatible shape.
Signals an invalid or unsupported type.
Matches all scalar types supported by Stratax numeric containers.
Definition Concepts.hpp:152
std::size_t checked_multiply(std::size_t lhs, std::size_t rhs, const char *message)
Multiplies two sizes while checking for overflow.
void require_same_value_type(const Lhs &, const Rhs &, const char *message)
Requires two array-like objects to have the same value type.
void require_same_shape(const Lhs &lhs, const Rhs &rhs, const char *message)
Requires two array-like objects to have identical size and shape.
std::size_t nonnegative_index(long long value, const char *message)
Converts a signed index to std::size_t after rejecting negatives.
bool same_shape(const Lhs &lhs, const Rhs &rhs)
Returns whether two array-like objects have identical size and shape.
void require_equal_size(std::size_t lhs, std::size_t rhs, const char *message)
Requires two sizes to be equal.
std::size_t nonnegative_size(long long value, const char *message)
Converts a signed value to std::size_t after rejecting negatives.
void require_index(std::size_t index, std::size_t size, const char *message)
Requires an index to be less than a size.
std::size_t positive_shape_dimension(long long value, const char *message)
Converts a signed shape dimension to std::size_t after requiring it to be positive.
void require_at_most(std::size_t value, std::size_t upper, const char *message)
Requires a value to be less than or equal to an upper bound.
void require_positive_shape_dimension(std::size_t value, const char *message)
Requires an unsigned shape dimension to be positive.
void require_rank(std::size_t actual, std::size_t expected, const char *message)
Requires a rank value to match an expected rank.
void require_type(const char *message)
Requires a type to exactly match an expected type after cv/ref removal.
void require_numeric_type(const char *message)
Requires a type to satisfy Stratax's numeric type rules.
std::size_t nonnegative_shape_dimension(long long value, const char *message)
Converts a signed shape dimension to std::size_t after rejecting negatives.
std::size_t checked_add(std::size_t lhs, std::size_t rhs, const char *message)
Adds two sizes while checking for overflow.