Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
CheckedConverter.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include <type_traits>
5
6#include "Stroika/Foundation/Execution/Throw.h"
7#include "Stroika/Foundation/Math/Common.h"
8
10
11 /*
12 ********************************************************************************
13 ***************************** DataExchange::Private_ ***************************
14 ********************************************************************************
15 */
16 namespace Private_ {
17 template <typename T>
18 inline T CheckedConverter_Range_Helper_Pinner_ (T t, T lower, T upper)
19 {
20 if constexpr (is_floating_point_v<T>) {
21 return Math::PinToSpecialPoint (Math::PinToSpecialPoint (t, lower), upper);
22 }
23 else {
24 // @todo review this code - where called - not sure why not pin in range too here?
25 return t;
26 }
27 }
28 }
29
30 /*
31 ********************************************************************************
32 ******************** DataExchange::CheckedConverter_Range **********************
33 ********************************************************************************
34 */
35 template <typename RANGE_TYPE>
36 RANGE_TYPE CheckedConverter_Range (const typename RANGE_TYPE::value_type& s, const typename RANGE_TYPE::value_type& e)
37 {
38 typename RANGE_TYPE::value_type useS =
39 Private_::CheckedConverter_Range_Helper_Pinner_ (s, RANGE_TYPE::TraitsType::kLowerBound, RANGE_TYPE::TraitsType::kUpperBound);
40 typename RANGE_TYPE::value_type useE =
41 Private_::CheckedConverter_Range_Helper_Pinner_ (e, RANGE_TYPE::TraitsType::kLowerBound, RANGE_TYPE::TraitsType::kUpperBound);
42 // Note: these checks MUST use <= and >= and IGNORE openness, because the bounds need not be in the range.
43 if (not(RANGE_TYPE::TraitsType::kLowerBound <= useS)) {
44 Execution::Throw (BadFormatException{"Value less than RangeType lower bounds"sv});
45 }
46 if (not(useS <= useE)) {
47 Execution::Throw (BadFormatException{"Range start must be less than or equal to end"sv});
48 }
49 if (not(useE <= RANGE_TYPE::TraitsType::kUpperBound)) {
50 Execution::Throw (BadFormatException{"Range end must be less than or equal to Range traits end"sv});
51 }
52 return RANGE_TYPE{useS, useE};
53 }
54
55 /*
56 ********************************************************************************
57 *************** DataExchange::CheckedConverter_ValueInRange ********************
58 ********************************************************************************
59 */
60 template <typename RANGE_TYPE>
61 typename RANGE_TYPE::value_type CheckedConverter_ValueInRange (typename RANGE_TYPE::value_type val, const RANGE_TYPE& range)
62 {
63 typename RANGE_TYPE::value_type useVal =
64 Private_::CheckedConverter_Range_Helper_Pinner_ (val, RANGE_TYPE::TraitsType::kLowerBound, RANGE_TYPE::TraitsType::kUpperBound);
65 if (not range.Contains (useVal)) {
66 if (useVal <= range.GetLowerBound ()) {
67 Execution::Throw (BadFormatException{"Value out of range (too low)"sv});
68 }
69 else {
70 Assert (useVal >= range.GetUpperBound ());
71 Execution::Throw (BadFormatException{"Value out of range (exceeds max)"sv});
72 }
73 }
74 return useVal;
75 }
76
77}
RANGE_TYPE CheckedConverter_Range(const typename RANGE_TYPE::value_type &s, const typename RANGE_TYPE::value_type &e)
RANGE_TYPE::ElementType CheckedConverter_ValueInRange(typename RANGE_TYPE::ElementType val, const RANGE_TYPE &range=RANGE_TYPE::FullRange())
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43