1 | // __ _____ _____ _____ |
2 | // __| | __| | | | JSON for Modern C++ |
3 | // | | |__ | | | | | | version 3.11.3 |
4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json |
5 | // |
6 | // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me> |
7 | // SPDX-FileCopyrightText: 2018 The Abseil Authors |
8 | // SPDX-License-Identifier: MIT |
9 | |
10 | #pragma once |
11 | |
12 | #include <array> // array |
13 | #include <cstddef> // size_t |
14 | #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type |
15 | #include <utility> // index_sequence, make_index_sequence, index_sequence_for |
16 | |
17 | #include <nlohmann/detail/macro_scope.hpp> |
18 | |
19 | NLOHMANN_JSON_NAMESPACE_BEGIN |
20 | namespace detail |
21 | { |
22 | |
23 | template<typename T> |
24 | using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type; |
25 | |
26 | #ifdef JSON_HAS_CPP_14 |
27 | |
28 | // the following utilities are natively available in C++14 |
29 | using std::enable_if_t; |
30 | using std::index_sequence; |
31 | using std::make_index_sequence; |
32 | using std::index_sequence_for; |
33 | |
34 | #else |
35 | |
36 | // alias templates to reduce boilerplate |
37 | template<bool B, typename T = void> |
38 | using enable_if_t = typename std::enable_if<B, T>::type; |
39 | |
40 | // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h |
41 | // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. |
42 | |
43 | //// START OF CODE FROM GOOGLE ABSEIL |
44 | |
45 | // integer_sequence |
46 | // |
47 | // Class template representing a compile-time integer sequence. An instantiation |
48 | // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its |
49 | // type through its template arguments (which is a common need when |
50 | // working with C++11 variadic templates). `absl::integer_sequence` is designed |
51 | // to be a drop-in replacement for C++14's `std::integer_sequence`. |
52 | // |
53 | // Example: |
54 | // |
55 | // template< class T, T... Ints > |
56 | // void user_function(integer_sequence<T, Ints...>); |
57 | // |
58 | // int main() |
59 | // { |
60 | // // user_function's `T` will be deduced to `int` and `Ints...` |
61 | // // will be deduced to `0, 1, 2, 3, 4`. |
62 | // user_function(make_integer_sequence<int, 5>()); |
63 | // } |
64 | template <typename T, T... Ints> |
65 | struct integer_sequence |
66 | { |
67 | using value_type = T; |
68 | static constexpr std::size_t size() noexcept |
69 | { |
70 | return sizeof...(Ints); |
71 | } |
72 | }; |
73 | |
74 | // index_sequence |
75 | // |
76 | // A helper template for an `integer_sequence` of `size_t`, |
77 | // `absl::index_sequence` is designed to be a drop-in replacement for C++14's |
78 | // `std::index_sequence`. |
79 | template <size_t... Ints> |
80 | using index_sequence = integer_sequence<size_t, Ints...>; |
81 | |
82 | namespace utility_internal |
83 | { |
84 | |
85 | template <typename Seq, size_t SeqSize, size_t Rem> |
86 | struct Extend; |
87 | |
88 | // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. |
89 | template <typename T, T... Ints, size_t SeqSize> |
90 | struct Extend<integer_sequence<T, Ints...>, SeqSize, 0> |
91 | { |
92 | using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; |
93 | }; |
94 | |
95 | template <typename T, T... Ints, size_t SeqSize> |
96 | struct Extend<integer_sequence<T, Ints...>, SeqSize, 1> |
97 | { |
98 | using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; |
99 | }; |
100 | |
101 | // Recursion helper for 'make_integer_sequence<T, N>'. |
102 | // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'. |
103 | template <typename T, size_t N> |
104 | struct Gen |
105 | { |
106 | using type = |
107 | typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; |
108 | }; |
109 | |
110 | template <typename T> |
111 | struct Gen<T, 0> |
112 | { |
113 | using type = integer_sequence<T>; |
114 | }; |
115 | |
116 | } // namespace utility_internal |
117 | |
118 | // Compile-time sequences of integers |
119 | |
120 | // make_integer_sequence |
121 | // |
122 | // This template alias is equivalent to |
123 | // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in |
124 | // replacement for C++14's `std::make_integer_sequence`. |
125 | template <typename T, T N> |
126 | using make_integer_sequence = typename utility_internal::Gen<T, N>::type; |
127 | |
128 | // make_index_sequence |
129 | // |
130 | // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, |
131 | // and is designed to be a drop-in replacement for C++14's |
132 | // `std::make_index_sequence`. |
133 | template <size_t N> |
134 | using make_index_sequence = make_integer_sequence<size_t, N>; |
135 | |
136 | // index_sequence_for |
137 | // |
138 | // Converts a typename pack into an index sequence of the same length, and |
139 | // is designed to be a drop-in replacement for C++14's |
140 | // `std::index_sequence_for()` |
141 | template <typename... Ts> |
142 | using index_sequence_for = make_index_sequence<sizeof...(Ts)>; |
143 | |
144 | //// END OF CODE FROM GOOGLE ABSEIL |
145 | |
146 | #endif |
147 | |
148 | // dispatch utility (taken from ranges-v3) |
149 | template<unsigned N> struct priority_tag : priority_tag < N - 1 > {}; |
150 | template<> struct priority_tag<0> {}; |
151 | |
152 | // taken from ranges-v3 |
153 | template<typename T> |
154 | struct static_const |
155 | { |
156 | static JSON_INLINE_VARIABLE constexpr T value{}; |
157 | }; |
158 | |
159 | #ifndef JSON_HAS_CPP_17 |
160 | template<typename T> |
161 | constexpr T static_const<T>::value; |
162 | #endif |
163 | |
164 | template<typename T, typename... Args> |
165 | inline constexpr std::array<T, sizeof...(Args)> make_array(Args&& ... args) |
166 | { |
167 | return std::array<T, sizeof...(Args)> {{static_cast<T>(std::forward<Args>(args))...}}; |
168 | } |
169 | |
170 | } // namespace detail |
171 | NLOHMANN_JSON_NAMESPACE_END |
172 | |