File indexing completed on 2025-01-18 09:36:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP
0014 #define BOOST_GEOMETRY_UTIL_TUPLES_HPP
0015
0016 #include <tuple>
0017 #include <type_traits>
0018 #include <utility>
0019
0020 #include <boost/geometry/core/config.hpp>
0021
0022 #include <boost/tuple/tuple.hpp>
0023
0024 namespace boost { namespace geometry { namespace tuples
0025 {
0026
0027 template <typename T>
0028 struct is_tuple
0029 : std::integral_constant<bool, false>
0030 {};
0031
0032 template <typename ...Ts>
0033 struct is_tuple<std::tuple<Ts...>>
0034 : std::integral_constant<bool, true>
0035 {};
0036
0037 template <typename F, typename S>
0038 struct is_tuple<std::pair<F, S>>
0039 : std::integral_constant<bool, true>
0040 {};
0041
0042 template <typename ...Ts>
0043 struct is_tuple<boost::tuples::tuple<Ts...>>
0044 : std::integral_constant<bool, true>
0045 {};
0046
0047 template <typename HT, typename TT>
0048 struct is_tuple<boost::tuples::cons<HT, TT>>
0049 : std::integral_constant<bool, true>
0050 {};
0051
0052
0053 template <std::size_t I, typename Tuple>
0054 struct element;
0055
0056 template <std::size_t I, typename ...Ts>
0057 struct element<I, std::tuple<Ts...>>
0058 : std::tuple_element<I, std::tuple<Ts...>>
0059 {};
0060
0061 template <std::size_t I, typename HT, typename TT>
0062 struct element<I, std::pair<HT, TT>>
0063 : std::tuple_element<I, std::pair<HT, TT>>
0064 {};
0065
0066 template <std::size_t I, typename ...Ts>
0067 struct element<I, boost::tuples::tuple<Ts...>>
0068 {
0069 typedef typename boost::tuples::element
0070 <
0071 I, boost::tuples::tuple<Ts...>
0072 >::type type;
0073 };
0074
0075 template <std::size_t I, typename HT, typename TT>
0076 struct element<I, boost::tuples::cons<HT, TT>>
0077 {
0078 typedef typename boost::tuples::element
0079 <
0080 I, boost::tuples::cons<HT, TT>
0081 >::type type;
0082 };
0083
0084
0085 template <typename Tuple>
0086 struct size;
0087
0088 template <typename ...Ts>
0089 struct size<std::tuple<Ts...>>
0090 : std::tuple_size<std::tuple<Ts...>>
0091 {};
0092
0093 template <typename HT, typename TT>
0094 struct size<std::pair<HT, TT>>
0095 : std::tuple_size<std::pair<HT, TT>>
0096 {};
0097
0098 template <typename ...Ts>
0099 struct size<boost::tuples::tuple<Ts...>>
0100 : std::integral_constant
0101 <
0102 std::size_t,
0103 boost::tuples::length<boost::tuples::tuple<Ts...>>::value
0104 >
0105 {};
0106
0107 template <typename HT, typename TT>
0108 struct size<boost::tuples::cons<HT, TT>>
0109 : std::integral_constant
0110 <
0111 std::size_t,
0112 boost::tuples::length<boost::tuples::cons<HT, TT>>::value
0113 >
0114 {};
0115
0116
0117 template <std::size_t I, typename ...Ts>
0118 constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type&
0119 get(std::tuple<Ts...> & t)
0120 {
0121 return std::get<I>(t);
0122 }
0123
0124 template <std::size_t I, typename ...Ts>
0125 constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type const&
0126 get(std::tuple<Ts...> const& t)
0127 {
0128 return std::get<I>(t);
0129 }
0130
0131 template <std::size_t I, typename HT, typename TT>
0132 constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type&
0133 get(std::pair<HT, TT> & t)
0134 {
0135 return std::get<I>(t);
0136 }
0137
0138 template <std::size_t I, typename HT, typename TT>
0139 constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type const&
0140 get(std::pair<HT, TT> const& t)
0141 {
0142 return std::get<I>(t);
0143 }
0144
0145 template <std::size_t I, typename ...Ts>
0146 inline typename boost::tuples::access_traits
0147 <
0148 typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
0149 >::non_const_type
0150 get(boost::tuples::tuple<Ts...> & t)
0151 {
0152 return boost::tuples::get<I>(t);
0153 }
0154
0155 template <std::size_t I, typename ...Ts>
0156 inline typename boost::tuples::access_traits
0157 <
0158 typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
0159 >::const_type
0160 get(boost::tuples::tuple<Ts...> const& t)
0161 {
0162 return boost::tuples::get<I>(t);
0163 }
0164
0165
0166 template <std::size_t I, typename HT, typename TT>
0167 inline typename boost::tuples::access_traits
0168 <
0169 typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
0170 >::non_const_type
0171 get(boost::tuples::cons<HT, TT> & tup)
0172 {
0173 return boost::tuples::get<I>(tup);
0174 }
0175
0176 template <std::size_t I, typename HT, typename TT>
0177 inline typename boost::tuples::access_traits
0178 <
0179 typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
0180 >::const_type
0181 get(boost::tuples::cons<HT, TT> const& tup)
0182 {
0183 return boost::tuples::get<I>(tup);
0184 }
0185
0186
0187
0188
0189
0190
0191
0192 template
0193 <
0194 typename Tuple,
0195 template <typename> class UnaryPred,
0196 std::size_t I = 0,
0197 std::size_t N = size<Tuple>::value
0198 >
0199 struct find_index_if
0200 : std::conditional_t
0201 <
0202 UnaryPred<typename element<I, Tuple>::type>::value,
0203 std::integral_constant<std::size_t, I>,
0204 typename find_index_if<Tuple, UnaryPred, I+1, N>::type
0205 >
0206 {};
0207
0208 template
0209 <
0210 typename Tuple,
0211 template <typename> class UnaryPred,
0212 std::size_t N
0213 >
0214 struct find_index_if<Tuple, UnaryPred, N, N>
0215 : std::integral_constant<std::size_t, N>
0216 {};
0217
0218
0219
0220
0221
0222
0223 namespace detail
0224 {
0225
0226 struct null_type {};
0227
0228 }
0229
0230 template
0231 <
0232 typename Tuple,
0233 template <typename> class UnaryPred,
0234 std::size_t I = 0,
0235 std::size_t N = size<Tuple>::value
0236 >
0237 struct find_if
0238 : std::conditional_t
0239 <
0240 UnaryPred<typename element<I, Tuple>::type>::value,
0241 element<I, Tuple>,
0242 find_if<Tuple, UnaryPred, I+1, N>
0243 >
0244 {};
0245
0246 template
0247 <
0248 typename Tuple,
0249 template <typename> class UnaryPred,
0250 std::size_t N
0251 >
0252 struct find_if<Tuple, UnaryPred, N, N>
0253 {
0254 typedef detail::null_type type;
0255 };
0256
0257
0258
0259
0260
0261 template <typename T>
0262 struct is_found
0263 : std::integral_constant
0264 <
0265 bool,
0266 ! std::is_same<T, detail::null_type>::value
0267 >
0268 {};
0269
0270
0271
0272
0273
0274 template <typename T>
0275 struct is_not_found
0276 : std::is_same<T, detail::null_type>
0277 {};
0278
0279
0280
0281
0282
0283 template <typename Tuple, template <typename> class UnaryPred>
0284 struct exists_if
0285 : is_found<typename find_if<Tuple, UnaryPred>::type>
0286 {};
0287
0288
0289
0290
0291
0292
0293 template <typename Tuple,
0294 typename T,
0295 std::size_t I = 0,
0296 std::size_t N = size<Tuple>::value>
0297 struct push_back_bt
0298 {
0299 typedef
0300 boost::tuples::cons<
0301 typename element<I, Tuple>::type,
0302 typename push_back_bt<Tuple, T, I+1, N>::type
0303 > type;
0304
0305 static type apply(Tuple const& tup, T const& t)
0306 {
0307 return
0308 type(
0309 geometry::tuples::get<I>(tup),
0310 push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
0311 );
0312 }
0313 };
0314
0315 template <typename Tuple, typename T, std::size_t N>
0316 struct push_back_bt<Tuple, T, N, N>
0317 {
0318 typedef boost::tuples::cons<T, boost::tuples::null_type> type;
0319
0320 static type apply(Tuple const&, T const& t)
0321 {
0322 return type(t, boost::tuples::null_type());
0323 }
0324 };
0325
0326 template <typename Tuple, typename T>
0327 struct push_back
0328 : push_back_bt<Tuple, T>
0329 {};
0330
0331 template <typename F, typename S, typename T>
0332 struct push_back<std::pair<F, S>, T>
0333 {
0334 typedef std::tuple<F, S, T> type;
0335
0336 static type apply(std::pair<F, S> const& p, T const& t)
0337 {
0338 return type(p.first, p.second, t);
0339 }
0340
0341 static type apply(std::pair<F, S> && p, T const& t)
0342 {
0343 return type(std::move(p.first), std::move(p.second), t);
0344 }
0345
0346 static type apply(std::pair<F, S> && p, T && t)
0347 {
0348 return type(std::move(p.first), std::move(p.second), std::move(t));
0349 }
0350 };
0351
0352 template <typename Is, typename Tuple, typename T>
0353 struct push_back_st;
0354
0355 template <std::size_t ...Is, typename ...Ts, typename T>
0356 struct push_back_st<std::index_sequence<Is...>, std::tuple<Ts...>, T>
0357 {
0358 typedef std::tuple<Ts..., T> type;
0359
0360 static type apply(std::tuple<Ts...> const& tup, T const& t)
0361 {
0362 return type(std::get<Is>(tup)..., t);
0363 }
0364
0365 static type apply(std::tuple<Ts...> && tup, T const& t)
0366 {
0367 return type(std::move(std::get<Is>(tup))..., t);
0368 }
0369
0370 static type apply(std::tuple<Ts...> && tup, T && t)
0371 {
0372 return type(std::move(std::get<Is>(tup))..., std::move(t));
0373 }
0374 };
0375
0376 template <typename ...Ts, typename T>
0377 struct push_back<std::tuple<Ts...>, T>
0378 : push_back_st
0379 <
0380 std::make_index_sequence<sizeof...(Ts)>,
0381 std::tuple<Ts...>,
0382 T
0383 >
0384 {};
0385
0386
0387 }}}
0388
0389 #endif