Loading [MathJax]/extensions/tex2jax.js
MeshKernel
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages Concepts
RangeCheck.hpp
1//---- GPL ---------------------------------------------------------------------
2//
3// Copyright (C) Stichting Deltares, 2011-2023.
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation version 3.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// contact: delft3d.support@deltares.nl
18// Stichting Deltares
19// P.O. Box 177
20// 2600 MH Delft, The Netherlands
21//
22// All indications and logos of, and references to, "Delft3D" and "Deltares"
23// are registered trademarks of Stichting Deltares, and remain the property of
24// Stichting Deltares. All rights reserved.
25//
26//------------------------------------------------------------------------------
27
28#pragma once
29
30#include "MeshKernel/Exceptions.hpp"
31#include "MeshKernel/Formatting.hpp"
32
33#include <algorithm>
34#include <concepts>
35#include <functional>
36#include <string>
37#include <string_view>
38#include <unordered_map>
39#include <utility>
40
41namespace meshkernel
42{
43 namespace range_check
44 {
46 template <typename T>
47 concept RangeCheckableType = std::floating_point<T> || (std::integral<T> &&
48 !std::same_as<T, bool> &&
49 !std::same_as<T, char> &&
50 !std::same_as<T, char8_t> &&
51 !std::same_as<T, char16_t> &&
52 !std::same_as<T, char32_t> &&
53 !std::same_as<T, wchar_t>);
54
56 enum class Comparison
57 {
58 Equal,
59 NotEqual,
60 Greater,
61 GreaterEqual,
62 Less,
63 LessEqual,
64 InClosedInterval,
65 InOpenInterval,
66 InRightHalfOpenInterval,
67 InLeftHalfOpenInterval,
68 OutsideClosedInterval,
69 OutsideOpenInterval,
70 OneOf,
71 NoneOf
72 };
73
75 inline static std::unordered_map<Comparison, std::string> const ValidRangeFormat = {
76 {Comparison::Equal, "value = {}"},
77 {Comparison::NotEqual, "value != {}"},
78 {Comparison::Greater, "value > {}"},
79 {Comparison::GreaterEqual, "value >= {}"},
80 {Comparison::Less, "value < {}"},
81 {Comparison::LessEqual, "value <= {}"},
82 {Comparison::InClosedInterval, "{} <= value <= {}"},
83 {Comparison::InOpenInterval, "{} < value < {}"},
84 {Comparison::InRightHalfOpenInterval, "{} <= value < {}"},
85 {Comparison::InLeftHalfOpenInterval, "{} < value <= {}"},
86 {Comparison::OutsideClosedInterval, "value < {} and value > {}"},
87 {Comparison::OutsideOpenInterval, "value <= {} and value >= {}"},
88 {Comparison::OneOf, "value is one of {}"},
89 {Comparison::NoneOf, "value is none of {}"}};
90
99 template <RangeCheckableType T>
100 inline static void CheckRange(T const& value,
101 T const& bound,
102 std::function<bool(T const&, T const&)> predicate,
103 Comparison const comparison,
104 std::string_view const variable_name)
105 {
106 if (!predicate(value, bound))
107 {
108 throw RangeError(
109 fmt_ns::format("{{}} = {{}} is invalid. Valid range: {}.",
110 ValidRangeFormat.at(comparison)),
111 variable_name,
112 value,
113 bound);
114 }
115 }
116
126 template <RangeCheckableType T>
127 inline static void CheckRange(T const& value,
128 T const& interval_lower_bound,
129 T const& interval_upper_bound,
130 std::function<bool(T const&, T const&, T const&)> predicate,
131 Comparison const comparison,
132 std::string_view const variable_name)
133 {
134 if (!predicate(value, interval_lower_bound, interval_upper_bound))
135 {
136 throw RangeError(
137 fmt_ns::format("{{}} = {{}} is invalid. Valid range: {}.",
138 ValidRangeFormat.at(comparison)),
139 variable_name,
140 value,
141 interval_lower_bound,
142 interval_upper_bound);
143 }
144 }
145
154 template <RangeCheckableType T>
155 inline static void CheckRange(T const& value,
156 std::vector<T> const& values,
157 std::function<bool(T const&, std::vector<T> const&)> predicate,
158 Comparison const comparison,
159 std::string_view const variable_name)
160 {
161 if (!predicate(value, values))
162 {
163 throw RangeError(
164 fmt_ns::format("{{}} = {{}} is invalid. Valid range: {}.",
165 ValidRangeFormat.at(comparison)),
166 variable_name,
167 value,
168 values);
169 }
170 }
171
178 template <RangeCheckableType T>
179 inline static void CheckEqual(T const& value,
180 T const& other_value,
181 std::string_view const variable_name)
182 {
183 CheckRange<T>(value,
184 other_value,
185 std::equal_to<T>(),
186 Comparison::Equal,
187 variable_name);
188 }
189
196 template <RangeCheckableType T>
197 inline static void CheckNotEqual(T const& value,
198 T const& other_value,
199 std::string_view const variable_name)
200 {
201 CheckRange<T>(value,
202 other_value,
203 std::not_equal_to<T>(),
204 Comparison::NotEqual,
205 variable_name);
206 }
207
214 template <RangeCheckableType T>
215 inline static void CheckGreater(T const& value,
216 T const& bound,
217 std::string_view const variable_name)
218 {
219 CheckRange<T>(value,
220 bound,
221 std::greater<T>(),
222 Comparison::Greater,
223 variable_name);
224 }
225
232 template <RangeCheckableType T>
233 inline static void CheckGreaterEqual(T const& value,
234 T const& bound,
235 std::string_view const variable_name)
236 {
237 CheckRange<T>(value,
238 bound,
239 std::greater_equal<T>(),
240 Comparison::GreaterEqual,
241 variable_name);
242 }
243
250 template <RangeCheckableType T>
251 inline static void CheckLess(T const& value,
252 T const& bound,
253 std::string_view const variable_name)
254 {
255 CheckRange<T>(value,
256 bound,
257 std::less<T>(),
258 Comparison::Less,
259 variable_name);
260 }
261
268 template <RangeCheckableType T>
269 inline static void CheckLessEqual(T const& value,
270 T const& bound,
271 std::string_view const variable_name)
272 {
273 CheckRange<T>(value,
274 bound,
275 std::less_equal<T>(),
276 Comparison::LessEqual,
277 variable_name);
278 }
279
287 template <RangeCheckableType T>
288 inline static void CheckInClosedInterval(T const& value,
289 T const& interval_lower_bound,
290 T const& interval_upper_bound,
291 std::string_view const variable_name)
292 {
293 auto const predicate = [](T const& v, T const& l, T const& u)
294 {
295 return std::less_equal{}(l, v) && std::less_equal{}(v, u);
296 };
297
298 CheckRange<T>(value,
299 interval_lower_bound,
300 interval_upper_bound,
301 predicate,
302 Comparison::InClosedInterval,
303 variable_name);
304 }
305
312 template <RangeCheckableType T>
313 inline static void CheckInClosedInterval(T const& value,
314 std::pair<T, T> const& inteval_bounds,
315 std::string_view const variable_name)
316 {
317 CheckInClosedInterval(value,
318 inteval_bounds.first,
319 inteval_bounds.second,
320 variable_name);
321 }
322
330 template <RangeCheckableType T>
331 inline static void CheckInOpenInterval(T const& value,
332 T const& interval_lower_bound,
333 T const& interval_upper_bound,
334 std::string_view const variable_name)
335 {
336 auto const predicate = [](T const& v, T const& l, T const& u)
337 {
338 return std::less{}(l, v) && std::less{}(v, u);
339 };
340
341 CheckRange<T>(value,
342 interval_lower_bound,
343 interval_upper_bound,
344 predicate,
345 Comparison::InOpenInterval,
346 variable_name);
347 }
348
355 template <RangeCheckableType T>
356 inline static void CheckInOpenInterval(T const& value,
357 std::pair<T, T> const& interval_bounds,
358 std::string_view const variable_name)
359 {
360 CheckInOpenInterval(value,
361 interval_bounds.first,
362 interval_bounds.second,
363 variable_name);
364 }
365
373 template <RangeCheckableType T>
374 inline static void CheckInRightHalfOpenInterval(T const& value,
375 T const& interval_lower_bound,
376 T const& interval_upper_bound,
377 std::string_view const variable_name)
378 {
379 auto const predicate = [](T const& v, T const& l, T const& u)
380 {
381 return std::less_equal{}(l, v) && std::less{}(v, u);
382 };
383
384 CheckRange<T>(value,
385 interval_lower_bound,
386 interval_upper_bound,
387 predicate,
388 Comparison::InRightHalfOpenInterval,
389 variable_name);
390 }
391
398 template <RangeCheckableType T>
399 inline static void CheckInRightHalfOpenInterval(T const& value,
400 std::pair<T, T> const& interval_bounds,
401 std::string_view const variable_name)
402 {
403 CheckInRightHalfOpenInterval(value,
404 interval_bounds.first,
405 interval_bounds.second,
406 variable_name);
407 }
408
416 template <RangeCheckableType T>
417 inline static void CheckInLeftHalfOpenInterval(T const& value,
418 T const& interval_lower_bound,
419 T const& interval_upper_bound,
420 std::string_view const variable_name)
421 {
422 auto const predicate = [](T const& v, T const& l, T const& u)
423 {
424 return std::less{}(l, v) && std::less_equal{}(v, u);
425 };
426
427 CheckRange<T>(value,
428 interval_lower_bound,
429 interval_upper_bound,
430 predicate,
431 Comparison::InLeftHalfOpenInterval,
432 variable_name);
433 }
434
441 template <RangeCheckableType T>
442 inline static void CheckInLeftHalfOpenInterval(T const& value,
443 std::pair<T, T> const& interval_bounds,
444 std::string_view const variable_name)
445 {
446 CheckInLeftHalfOpenInterval(value,
447 interval_bounds.first,
448 interval_bounds.second,
449 variable_name);
450 }
451
459 template <RangeCheckableType T>
460 inline static void CheckOutsideClosedInterval(T const& value,
461 T const& interval_lower_bound,
462 T const& interval_upper_bound,
463 std::string_view const variable_name)
464 {
465 auto const predicate = [](T const& v, T const& l, T const& u)
466 {
467 return std::less{}(v, l) || std::greater{}(v, u);
468 };
469
470 CheckRange<T>(value,
471 interval_lower_bound,
472 interval_upper_bound,
473 predicate,
474 Comparison::OutsideClosedInterval,
475 variable_name);
476 }
477
484 template <RangeCheckableType T>
485 inline static void CheckOutsideClosedInterval(T const& value,
486 std::pair<T, T> const& interval_bounds,
487 std::string_view const variable_name)
488 {
489 CheckOutsideClosedInterval(value,
490 interval_bounds.first,
491 interval_bounds.second,
492 variable_name);
493 }
494
502 template <RangeCheckableType T>
503 inline static void CheckOutsideOpenInterval(T const& value,
504 T const& interval_lower_bound,
505 T const& interval_upper_bound,
506 std::string_view const variable_name)
507 {
508 auto const predicate = [](T const& v, T const& l, T const& u)
509 {
510 return std::less_equal{}(v, l) || std::greater_equal{}(v, u);
511 };
512
513 CheckRange<T>(value,
514 interval_lower_bound,
515 interval_upper_bound,
516 predicate,
517 Comparison::OutsideClosedInterval,
518 variable_name);
519 }
520
527 template <RangeCheckableType T>
528 inline static void CheckOutsideOpenInterval(T const& value,
529 std::pair<T, T> const& interval_bounds,
530 std::string_view const variable_name)
531 {
532 CheckOutsideOpenInterval(value,
533 interval_bounds.first,
534 interval_bounds.second,
535 variable_name);
536 }
537
544 template <RangeCheckableType T>
545 inline static void CheckOneOf(T const& value,
546 std::vector<T> const& values,
547 std::string_view const variable_name)
548 {
549 auto const predicate = [](T const& v, std::vector<T> const& l)
550 {
551 return std::any_of(l.begin(), l.end(), [&v](T const& i)
552 { return std::equal_to<T>{}(i, v); });
553 };
554
555 CheckRange<T>(value,
556 values,
557 predicate,
558 Comparison::OneOf,
559 variable_name);
560 }
561
568 template <RangeCheckableType T>
569 inline static void CheckNoneOf(T const& value,
570 std::vector<T> const& values,
571 std::string_view const variable_name)
572 {
573 auto const predicate = [](T const& v, std::vector<T> const& l)
574 {
575 return std::none_of(l.begin(), l.end(), [&v](T const& i)
576 { return std::equal_to<T>{}(i, v); });
577 };
578
579 CheckRange<T>(value,
580 values,
581 predicate,
582 Comparison::NoneOf,
583 variable_name);
584 }
585
593 template <RangeCheckableType T, class Precondition>
594 inline static void CheckPrecondition(T const& value,
595 std::string_view const variable_name,
596 std::string_view const precondition_name,
597 Precondition precondition)
598 {
599 if (!precondition(value))
600 {
601 throw RangeError("{{}} = {{}} precondition not satisfied: value should satisfy: {}",
602 variable_name,
603 value,
604 precondition_name);
605 }
606 }
607
608 } // namespace range_check
609
610} // namespace meshkernel
Defines the checkable types: floating point types and inetgral types except for bool and char.
Definition RangeCheck.hpp:47
Contains the logic of the C++ static library.
Definition AveragingInterpolation.hpp:37