Enhanced SIM for E2AP v1 for TS UC
[sim/e2-interface.git] / e2sim / e2apv1sim / src / ASN1 / asn / constraints.hpp
1 #pragma once
2
3 /******************************************************************************
4 *
5 *   Copyright (c) 2019 AT&T Intellectual Property.
6 *   Copyright (c) 2018-2019 Nokia.
7 *
8 *   Licensed under the Apache License, Version 2.0 (the "License");
9 *   you may not use this file except in compliance with the License.
10 *   You may obtain a copy of the License at
11 *
12 *       http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *   Unless required by applicable law or agreed to in writing, software
15 *   distributed under the License is distributed on an "AS IS" BASIS,
16 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 *   See the License for the specific language governing permissions and
18 *   limitations under the License.
19 *
20 *
21 ******************************************************************************/
22
23 // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries
24 #include <limits>
25 #include <type_traits>
26 #include <algorithm>
27 #include <array>
28
29 // Local Includes: Application specific classes, functions, and libraries
30
31 namespace asn {
32
33 using bound_t = int64_t;
34
35 enum class constraint_type : uint8_t
36 {
37         UNCONSTRAINED,
38         CONSTRAINED,
39         SEMICONSTRAINED,
40         CONSTRAINED_EXTENDED,
41         SEMICONSTRAINED_EXTENDED
42 };
43
44 template <bound_t LB, bound_t UB>
45 struct span
46 {
47         static_assert(UB >= LB, "UPPER >= LOWER");
48         static constexpr bound_t lower_bound = LB;
49         static constexpr bound_t upper_bound = UB;
50 };
51
52 template <typename T>
53 struct pair
54 {
55         T const lower_bound;
56         T const upper_bound;
57 };
58
59 template <bound_t VALUE>
60 struct one : span<VALUE, VALUE> {};
61
62 struct max : one<std::numeric_limits<bound_t>::max()> {};
63 struct min : one<std::numeric_limits<bound_t>::min()> {};
64
65 static constexpr bound_t MAX = std::numeric_limits<bound_t>::max();
66 static constexpr bound_t MIN = std::numeric_limits<bound_t>::min();
67
68 template <bool Extended, class... RANGE>
69 struct constraints
70 {
71         static constexpr bool extended = Extended;
72         static constexpr bound_t lower_bound = std::min({RANGE::lower_bound...});
73         static constexpr bound_t upper_bound = std::max({RANGE::upper_bound...});
74
75         static constexpr constraint_type type =
76                         (Extended && lower_bound > min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::CONSTRAINED_EXTENDED :
77                                 (!Extended && lower_bound > min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::CONSTRAINED :
78                                         (Extended && lower_bound > min::lower_bound && upper_bound == max::upper_bound) ? constraint_type::SEMICONSTRAINED_EXTENDED :
79                                                 (!Extended && lower_bound == min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::SEMICONSTRAINED : 
80                                                         (Extended && lower_bound == min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::SEMICONSTRAINED_EXTENDED :
81                                                                 (!Extended && lower_bound > min::lower_bound && upper_bound == max::upper_bound) ? constraint_type::SEMICONSTRAINED : constraint_type::UNCONSTRAINED;
82         
83         static constexpr bool is_signed = lower_bound < 0;
84
85         static constexpr bound_t num_spans = static_cast<bound_t>(sizeof...(RANGE));
86         static constexpr pair<bound_t> bounds[] = {{RANGE::lower_bound, RANGE::upper_bound}...};
87         
88         using boundary_type = bound_t;
89
90         static constexpr bool is_extended(bound_t val)
91         {
92                 for (bound_t i = 0; i < num_spans; ++i)
93                 {
94                         auto const& p = bounds[i];
95                         if (val <= p.upper_bound)
96                         {
97                                 if(val < p.lower_bound)
98                                         return true;
99                                 return false;
100                         }
101                 }
102                 return true;
103         }
104 };
105
106 template <bool Extended, class... RANGE>
107 constexpr pair<bound_t> constraints<Extended, RANGE...>::bounds[];
108
109 template <bool Extended>
110 struct constraints<Extended>
111 {
112         static constexpr bool extended = Extended;
113         static constexpr constraint_type type = constraint_type::UNCONSTRAINED;
114         static constexpr bound_t lower_bound = std::numeric_limits<bound_t>::min();
115         static constexpr bound_t upper_bound = std::numeric_limits<bound_t>::max();
116         
117         static constexpr bool is_extended(bound_t val) {return true;}
118 };
119
120 /***************************************************************************************
121 * RANGE for sequences
122 ***************************************************************************************/
123 template<int TotalNumEntries, int NumExtEntries, bool Extended>
124 struct seq_range
125 {
126         static_assert(Extended || TotalNumEntries > 0, "TotalNumEntries must be > 0");
127         static_assert(NumExtEntries <= TotalNumEntries, "NumExtEntries must be <= TotalNumEntries");
128         
129         static constexpr constraint_type type           = Extended ? constraint_type::CONSTRAINED_EXTENDED : constraint_type::CONSTRAINED;
130         static constexpr bool extended                          = Extended;
131         static constexpr bound_t lower_bound            = 0;
132         static constexpr bound_t upper_bound            = TotalNumEntries - NumExtEntries - 1;
133         static constexpr bound_t default_value          = lower_bound;
134         static constexpr bound_t total_num_entries      = TotalNumEntries;
135         
136         using boundary_type = bound_t;
137         using value_type        = uint32_t;
138 };
139
140 } // namespace asn