| #pragma once |
| |
| /****************************************************************************** |
| * |
| * Copyright (c) 2019 AT&T Intellectual Property. |
| * Copyright (c) 2018-2019 Nokia. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * |
| ******************************************************************************/ |
| |
| // Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries |
| #include <limits> |
| #include <type_traits> |
| #include <algorithm> |
| #include <array> |
| |
| // Local Includes: Application specific classes, functions, and libraries |
| |
| namespace asn { |
| |
| using bound_t = int64_t; |
| |
| enum class constraint_type : uint8_t |
| { |
| UNCONSTRAINED, |
| CONSTRAINED, |
| SEMICONSTRAINED, |
| CONSTRAINED_EXTENDED, |
| SEMICONSTRAINED_EXTENDED |
| }; |
| |
| template <bound_t LB, bound_t UB> |
| struct span |
| { |
| static_assert(UB >= LB, "UPPER >= LOWER"); |
| static constexpr bound_t lower_bound = LB; |
| static constexpr bound_t upper_bound = UB; |
| }; |
| |
| template <typename T> |
| struct pair |
| { |
| T const lower_bound; |
| T const upper_bound; |
| }; |
| |
| template <bound_t VALUE> |
| struct one : span<VALUE, VALUE> {}; |
| |
| struct max : one<std::numeric_limits<bound_t>::max()> {}; |
| struct min : one<std::numeric_limits<bound_t>::min()> {}; |
| |
| static constexpr bound_t MAX = std::numeric_limits<bound_t>::max(); |
| static constexpr bound_t MIN = std::numeric_limits<bound_t>::min(); |
| |
| template <bool Extended, class... RANGE> |
| struct constraints |
| { |
| static constexpr bool extended = Extended; |
| static constexpr bound_t lower_bound = std::min({RANGE::lower_bound...}); |
| static constexpr bound_t upper_bound = std::max({RANGE::upper_bound...}); |
| |
| static constexpr constraint_type type = |
| (Extended && lower_bound > min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::CONSTRAINED_EXTENDED : |
| (!Extended && lower_bound > min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::CONSTRAINED : |
| (Extended && lower_bound > min::lower_bound && upper_bound == max::upper_bound) ? constraint_type::SEMICONSTRAINED_EXTENDED : |
| (!Extended && lower_bound == min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::SEMICONSTRAINED : |
| (Extended && lower_bound == min::lower_bound && upper_bound < max::upper_bound) ? constraint_type::SEMICONSTRAINED_EXTENDED : |
| (!Extended && lower_bound > min::lower_bound && upper_bound == max::upper_bound) ? constraint_type::SEMICONSTRAINED : constraint_type::UNCONSTRAINED; |
| |
| static constexpr bool is_signed = lower_bound < 0; |
| |
| static constexpr bound_t num_spans = static_cast<bound_t>(sizeof...(RANGE)); |
| static constexpr pair<bound_t> bounds[] = {{RANGE::lower_bound, RANGE::upper_bound}...}; |
| |
| using boundary_type = bound_t; |
| |
| static constexpr bool is_extended(bound_t val) |
| { |
| for (bound_t i = 0; i < num_spans; ++i) |
| { |
| auto const& p = bounds[i]; |
| if (val <= p.upper_bound) |
| { |
| if(val < p.lower_bound) |
| return true; |
| return false; |
| } |
| } |
| return true; |
| } |
| }; |
| |
| template <bool Extended, class... RANGE> |
| constexpr pair<bound_t> constraints<Extended, RANGE...>::bounds[]; |
| |
| template <bool Extended> |
| struct constraints<Extended> |
| { |
| static constexpr bool extended = Extended; |
| static constexpr constraint_type type = constraint_type::UNCONSTRAINED; |
| static constexpr bound_t lower_bound = std::numeric_limits<bound_t>::min(); |
| static constexpr bound_t upper_bound = std::numeric_limits<bound_t>::max(); |
| |
| static constexpr bool is_extended(bound_t val) {return true;} |
| }; |
| |
| /*************************************************************************************** |
| * RANGE for sequences |
| ***************************************************************************************/ |
| template<int TotalNumEntries, int NumExtEntries, bool Extended> |
| struct seq_range |
| { |
| static_assert(Extended || TotalNumEntries > 0, "TotalNumEntries must be > 0"); |
| static_assert(NumExtEntries <= TotalNumEntries, "NumExtEntries must be <= TotalNumEntries"); |
| |
| static constexpr constraint_type type = Extended ? constraint_type::CONSTRAINED_EXTENDED : constraint_type::CONSTRAINED; |
| static constexpr bool extended = Extended; |
| static constexpr bound_t lower_bound = 0; |
| static constexpr bound_t upper_bound = TotalNumEntries - NumExtEntries - 1; |
| static constexpr bound_t default_value = lower_bound; |
| static constexpr bound_t total_num_entries = TotalNumEntries; |
| |
| using boundary_type = bound_t; |
| using value_type = uint32_t; |
| }; |
| |
| } // namespace asn |