File indexing completed on 2025-01-18 09:36:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GEOMETRY_UTIL_SEQUENCE_HPP
0011 #define BOOST_GEOMETRY_UTIL_SEQUENCE_HPP
0012
0013 #include <utility>
0014 #include <type_traits>
0015
0016
0017 namespace boost { namespace geometry
0018 {
0019
0020 namespace util
0021 {
0022
0023
0024
0025
0026
0027
0028 template <typename ...Ts>
0029 struct type_sequence {};
0030
0031
0032
0033 template <typename T>
0034 struct is_sequence : std::false_type {};
0035
0036 template <typename ...Ts>
0037 struct is_sequence<type_sequence<Ts...>> : std::true_type {};
0038
0039 template <typename T, T ...Is>
0040 struct is_sequence<std::integer_sequence<T, Is...>> : std::true_type {};
0041
0042
0043
0044 template <typename Sequence>
0045 struct sequence_size {};
0046
0047 template <typename ...Ts>
0048 struct sequence_size<type_sequence<Ts...>>
0049 : std::integral_constant<std::size_t, sizeof...(Ts)>
0050 {};
0051
0052 template <typename T, T ...Is>
0053 struct sequence_size<std::integer_sequence<T, Is...>>
0054 : std::integral_constant<std::size_t, sizeof...(Is)>
0055 {};
0056
0057
0058
0059 template <std::size_t I, typename Sequence>
0060 struct sequence_element {};
0061
0062 template <std::size_t I, typename T, typename ...Ts>
0063 struct sequence_element<I, type_sequence<T, Ts...>>
0064 {
0065 using type = typename sequence_element<I - 1, type_sequence<Ts...>>::type;
0066 };
0067
0068 template <typename T, typename ...Ts>
0069 struct sequence_element<0, type_sequence<T, Ts...>>
0070 {
0071 using type = T;
0072 };
0073
0074 template <std::size_t I, typename T, T J, T ...Js>
0075 struct sequence_element<I, std::integer_sequence<T, J, Js...>>
0076 : std::integral_constant
0077 <
0078 T,
0079 sequence_element<I - 1, std::integer_sequence<T, Js...>>::value
0080 >
0081 {};
0082
0083 template <typename T, T J, T ...Js>
0084 struct sequence_element<0, std::integer_sequence<T, J, Js...>>
0085 : std::integral_constant<T, J>
0086 {};
0087
0088
0089 template <typename ...Ts>
0090 struct pack_front
0091 {
0092 static_assert(sizeof...(Ts) > 0, "Parameter pack can not be empty.");
0093 };
0094
0095 template <typename T, typename ... Ts>
0096 struct pack_front<T, Ts...>
0097 {
0098 typedef T type;
0099 };
0100
0101
0102 template <typename Sequence>
0103 struct sequence_front
0104 : sequence_element<0, Sequence>
0105 {
0106 static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
0107 };
0108
0109
0110 template <typename Sequence>
0111 struct sequence_back
0112 : sequence_element<sequence_size<Sequence>::value - 1, Sequence>
0113 {
0114 static_assert(sequence_size<Sequence>::value > 0, "Sequence can not be empty.");
0115 };
0116
0117
0118 template <typename Sequence>
0119 struct sequence_empty
0120 : std::integral_constant
0121 <
0122 bool,
0123 sequence_size<Sequence>::value == 0
0124 >
0125 {};
0126
0127
0128
0129 template
0130 <
0131 typename Sequence,
0132 template <typename> class UnaryPred
0133 >
0134 struct sequence_find_if {};
0135
0136 template
0137 <
0138 typename T, typename ...Ts,
0139 template <typename> class UnaryPred
0140 >
0141 struct sequence_find_if<type_sequence<T, Ts...>, UnaryPred>
0142 : std::conditional
0143 <
0144 UnaryPred<T>::value,
0145 T,
0146
0147 typename sequence_find_if<type_sequence<Ts...>, UnaryPred>::type
0148 >
0149 {};
0150
0151 template <template <typename> class UnaryPred>
0152 struct sequence_find_if<type_sequence<>, UnaryPred>
0153 {
0154
0155 using type = void;
0156 };
0157
0158
0159
0160
0161
0162
0163 template <typename ...Sequences>
0164 struct sequence_merge;
0165
0166 template <typename S>
0167 struct sequence_merge<S>
0168 {
0169 using type = S;
0170 };
0171
0172 template <typename ...T1s, typename ...T2s>
0173 struct sequence_merge<type_sequence<T1s...>, type_sequence<T2s...>>
0174 {
0175 using type = type_sequence<T1s..., T2s...>;
0176 };
0177
0178 template <typename T, T ...I1s, T ...I2s>
0179 struct sequence_merge<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
0180 {
0181 using type = std::integer_sequence<T, I1s..., I2s...>;
0182 };
0183
0184 template <typename S1, typename S2, typename ...Sequences>
0185 struct sequence_merge<S1, S2, Sequences...>
0186 {
0187 using type = typename sequence_merge
0188 <
0189 typename sequence_merge<S1, S2>::type,
0190 typename sequence_merge<Sequences...>::type
0191 >::type;
0192 };
0193
0194
0195
0196
0197
0198 template <typename Sequence1, typename Sequence2>
0199 struct sequence_combine;
0200
0201 template <typename ...T1s, typename ...T2s>
0202 struct sequence_combine<type_sequence<T1s...>, type_sequence<T2s...>>
0203 {
0204 template <typename T1>
0205 using type_sequence_t = type_sequence<type_sequence<T1, T2s>...>;
0206
0207 using type = typename sequence_merge<type_sequence_t<T1s>...>::type;
0208 };
0209
0210
0211
0212
0213 template <typename T, T ...I1s, T ...I2s>
0214 struct sequence_combine<std::integer_sequence<T, I1s...>, std::integer_sequence<T, I2s...>>
0215 {
0216 template <T I1>
0217 using type_sequence_t = type_sequence<std::integer_sequence<T, I1, I2s>...>;
0218
0219 using type = typename sequence_merge<type_sequence_t<I1s>...>::type;
0220 };
0221
0222
0223
0224
0225 template
0226 <
0227 template <typename, typename> class LessPred,
0228 typename ...Ts
0229 >
0230 struct pack_min_element;
0231
0232 template
0233 <
0234 template <typename, typename> class LessPred,
0235 typename T
0236 >
0237 struct pack_min_element<LessPred, T>
0238 {
0239 using type = T;
0240 };
0241
0242 template
0243 <
0244 template <typename, typename> class LessPred,
0245 typename T1, typename T2
0246 >
0247 struct pack_min_element<LessPred, T1, T2>
0248 {
0249 using type = std::conditional_t<LessPred<T1, T2>::value, T1, T2>;
0250 };
0251
0252 template
0253 <
0254 template <typename, typename> class LessPred,
0255 typename T1, typename T2, typename ...Ts
0256 >
0257 struct pack_min_element<LessPred, T1, T2, Ts...>
0258 {
0259 using type = typename pack_min_element
0260 <
0261 LessPred,
0262 typename pack_min_element<LessPred, T1, T2>::type,
0263 typename pack_min_element<LessPred, Ts...>::type
0264 >::type;
0265 };
0266
0267
0268
0269
0270 template
0271 <
0272 typename Sequence,
0273 template <typename, typename> class LessPred
0274 >
0275 struct sequence_min_element;
0276
0277 template
0278 <
0279 typename ...Ts,
0280 template <typename, typename> class LessPred
0281 >
0282 struct sequence_min_element<type_sequence<Ts...>, LessPred>
0283 {
0284 using type = typename pack_min_element<LessPred, Ts...>::type;
0285 };
0286
0287
0288
0289
0290
0291
0292
0293 }
0294
0295
0296 }}
0297
0298
0299 #endif