390 lines
8.9 KiB
C++
390 lines
8.9 KiB
C++
|
// Boost.Geometry Index
|
||
|
//
|
||
|
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
|
||
|
//
|
||
|
// This file was modified by Oracle on 2019-2020.
|
||
|
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
|
||
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||
|
//
|
||
|
// Use, modification and distribution is subject to the Boost Software License,
|
||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||
|
|
||
|
#ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP
|
||
|
#define BOOST_GEOMETRY_UTIL_TUPLES_HPP
|
||
|
|
||
|
#include <tuple>
|
||
|
#include <type_traits>
|
||
|
#include <utility>
|
||
|
|
||
|
#include <boost/geometry/core/config.hpp>
|
||
|
|
||
|
#include <boost/tuple/tuple.hpp>
|
||
|
|
||
|
namespace boost { namespace geometry { namespace tuples
|
||
|
{
|
||
|
|
||
|
template <typename T>
|
||
|
struct is_tuple
|
||
|
: std::integral_constant<bool, false>
|
||
|
{};
|
||
|
|
||
|
template <typename ...Ts>
|
||
|
struct is_tuple<std::tuple<Ts...>>
|
||
|
: std::integral_constant<bool, true>
|
||
|
{};
|
||
|
|
||
|
template <typename F, typename S>
|
||
|
struct is_tuple<std::pair<F, S>>
|
||
|
: std::integral_constant<bool, true>
|
||
|
{};
|
||
|
|
||
|
template <typename ...Ts>
|
||
|
struct is_tuple<boost::tuples::tuple<Ts...>>
|
||
|
: std::integral_constant<bool, true>
|
||
|
{};
|
||
|
|
||
|
template <typename HT, typename TT>
|
||
|
struct is_tuple<boost::tuples::cons<HT, TT>>
|
||
|
: std::integral_constant<bool, true>
|
||
|
{};
|
||
|
|
||
|
|
||
|
template <std::size_t I, typename Tuple>
|
||
|
struct element;
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
struct element<I, std::tuple<Ts...>>
|
||
|
: std::tuple_element<I, std::tuple<Ts...>>
|
||
|
{};
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
struct element<I, std::pair<HT, TT>>
|
||
|
: std::tuple_element<I, std::pair<HT, TT>>
|
||
|
{};
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
struct element<I, boost::tuples::tuple<Ts...>>
|
||
|
{
|
||
|
typedef typename boost::tuples::element
|
||
|
<
|
||
|
I, boost::tuples::tuple<Ts...>
|
||
|
>::type type;
|
||
|
};
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
struct element<I, boost::tuples::cons<HT, TT>>
|
||
|
{
|
||
|
typedef typename boost::tuples::element
|
||
|
<
|
||
|
I, boost::tuples::cons<HT, TT>
|
||
|
>::type type;
|
||
|
};
|
||
|
|
||
|
|
||
|
template <typename Tuple>
|
||
|
struct size;
|
||
|
|
||
|
template <typename ...Ts>
|
||
|
struct size<std::tuple<Ts...>>
|
||
|
: std::tuple_size<std::tuple<Ts...>>
|
||
|
{};
|
||
|
|
||
|
template <typename HT, typename TT>
|
||
|
struct size<std::pair<HT, TT>>
|
||
|
: std::tuple_size<std::pair<HT, TT>>
|
||
|
{};
|
||
|
|
||
|
template <typename ...Ts>
|
||
|
struct size<boost::tuples::tuple<Ts...>>
|
||
|
: std::integral_constant
|
||
|
<
|
||
|
std::size_t,
|
||
|
boost::tuples::length<boost::tuples::tuple<Ts...>>::value
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
template <typename HT, typename TT>
|
||
|
struct size<boost::tuples::cons<HT, TT>>
|
||
|
: std::integral_constant
|
||
|
<
|
||
|
std::size_t,
|
||
|
boost::tuples::length<boost::tuples::cons<HT, TT>>::value
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type&
|
||
|
get(std::tuple<Ts...> & t)
|
||
|
{
|
||
|
return std::get<I>(t);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
constexpr inline typename std::tuple_element<I, std::tuple<Ts...>>::type const&
|
||
|
get(std::tuple<Ts...> const& t)
|
||
|
{
|
||
|
return std::get<I>(t);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type&
|
||
|
get(std::pair<HT, TT> & t)
|
||
|
{
|
||
|
return std::get<I>(t);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
constexpr inline typename std::tuple_element<I, std::pair<HT, TT>>::type const&
|
||
|
get(std::pair<HT, TT> const& t)
|
||
|
{
|
||
|
return std::get<I>(t);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
inline typename boost::tuples::access_traits
|
||
|
<
|
||
|
typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
|
||
|
>::non_const_type
|
||
|
get(boost::tuples::tuple<Ts...> & t)
|
||
|
{
|
||
|
return boost::tuples::get<I>(t);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename ...Ts>
|
||
|
inline typename boost::tuples::access_traits
|
||
|
<
|
||
|
typename boost::tuples::element<I, boost::tuples::tuple<Ts...>>::type
|
||
|
>::const_type
|
||
|
get(boost::tuples::tuple<Ts...> const& t)
|
||
|
{
|
||
|
return boost::tuples::get<I>(t);
|
||
|
}
|
||
|
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
inline typename boost::tuples::access_traits
|
||
|
<
|
||
|
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
|
||
|
>::non_const_type
|
||
|
get(boost::tuples::cons<HT, TT> & tup)
|
||
|
{
|
||
|
return boost::tuples::get<I>(tup);
|
||
|
}
|
||
|
|
||
|
template <std::size_t I, typename HT, typename TT>
|
||
|
inline typename boost::tuples::access_traits
|
||
|
<
|
||
|
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
|
||
|
>::const_type
|
||
|
get(boost::tuples::cons<HT, TT> const& tup)
|
||
|
{
|
||
|
return boost::tuples::get<I>(tup);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// find_index_if
|
||
|
// Searches for the index of an element for which UnaryPredicate returns true
|
||
|
// If such element is not found the result is N
|
||
|
|
||
|
template
|
||
|
<
|
||
|
typename Tuple,
|
||
|
template <typename> class UnaryPred,
|
||
|
std::size_t I = 0,
|
||
|
std::size_t N = size<Tuple>::value
|
||
|
>
|
||
|
struct find_index_if
|
||
|
: std::conditional_t
|
||
|
<
|
||
|
UnaryPred<typename element<I, Tuple>::type>::value,
|
||
|
std::integral_constant<std::size_t, I>,
|
||
|
typename find_index_if<Tuple, UnaryPred, I+1, N>::type
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
template
|
||
|
<
|
||
|
typename Tuple,
|
||
|
template <typename> class UnaryPred,
|
||
|
std::size_t N
|
||
|
>
|
||
|
struct find_index_if<Tuple, UnaryPred, N, N>
|
||
|
: std::integral_constant<std::size_t, N>
|
||
|
{};
|
||
|
|
||
|
|
||
|
// find_if
|
||
|
// Searches for an element for which UnaryPredicate returns true
|
||
|
// If such element is not found the result is detail::null_type
|
||
|
|
||
|
namespace detail
|
||
|
{
|
||
|
|
||
|
struct null_type {};
|
||
|
|
||
|
} // detail
|
||
|
|
||
|
template
|
||
|
<
|
||
|
typename Tuple,
|
||
|
template <typename> class UnaryPred,
|
||
|
std::size_t I = 0,
|
||
|
std::size_t N = size<Tuple>::value
|
||
|
>
|
||
|
struct find_if
|
||
|
: std::conditional_t
|
||
|
<
|
||
|
UnaryPred<typename element<I, Tuple>::type>::value,
|
||
|
element<I, Tuple>,
|
||
|
find_if<Tuple, UnaryPred, I+1, N>
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
template
|
||
|
<
|
||
|
typename Tuple,
|
||
|
template <typename> class UnaryPred,
|
||
|
std::size_t N
|
||
|
>
|
||
|
struct find_if<Tuple, UnaryPred, N, N>
|
||
|
{
|
||
|
typedef detail::null_type type;
|
||
|
};
|
||
|
|
||
|
|
||
|
// is_found
|
||
|
// Returns true if a type T (the result of find_if) was found.
|
||
|
|
||
|
template <typename T>
|
||
|
struct is_found
|
||
|
: std::integral_constant
|
||
|
<
|
||
|
bool,
|
||
|
! std::is_same<T, detail::null_type>::value
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
|
||
|
// is_not_found
|
||
|
// Returns true if a type T (the result of find_if) was not found.
|
||
|
|
||
|
template <typename T>
|
||
|
struct is_not_found
|
||
|
: std::is_same<T, detail::null_type>
|
||
|
{};
|
||
|
|
||
|
|
||
|
// exists_if
|
||
|
// Returns true if search for element meeting UnaryPred can be found.
|
||
|
|
||
|
template <typename Tuple, template <typename> class UnaryPred>
|
||
|
struct exists_if
|
||
|
: is_found<typename find_if<Tuple, UnaryPred>::type>
|
||
|
{};
|
||
|
|
||
|
|
||
|
// push_back
|
||
|
// A utility used to create a type/object of a Tuple containing
|
||
|
// all types/objects stored in another Tuple plus additional one.
|
||
|
|
||
|
template <typename Tuple,
|
||
|
typename T,
|
||
|
std::size_t I = 0,
|
||
|
std::size_t N = size<Tuple>::value>
|
||
|
struct push_back_bt
|
||
|
{
|
||
|
typedef
|
||
|
boost::tuples::cons<
|
||
|
typename element<I, Tuple>::type,
|
||
|
typename push_back_bt<Tuple, T, I+1, N>::type
|
||
|
> type;
|
||
|
|
||
|
static type apply(Tuple const& tup, T const& t)
|
||
|
{
|
||
|
return
|
||
|
type(
|
||
|
geometry::tuples::get<I>(tup),
|
||
|
push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
|
||
|
);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Tuple, typename T, std::size_t N>
|
||
|
struct push_back_bt<Tuple, T, N, N>
|
||
|
{
|
||
|
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
|
||
|
|
||
|
static type apply(Tuple const&, T const& t)
|
||
|
{
|
||
|
return type(t, boost::tuples::null_type());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Tuple, typename T>
|
||
|
struct push_back
|
||
|
: push_back_bt<Tuple, T>
|
||
|
{};
|
||
|
|
||
|
template <typename F, typename S, typename T>
|
||
|
struct push_back<std::pair<F, S>, T>
|
||
|
{
|
||
|
typedef std::tuple<F, S, T> type;
|
||
|
|
||
|
static type apply(std::pair<F, S> const& p, T const& t)
|
||
|
{
|
||
|
return type(p.first, p.second, t);
|
||
|
}
|
||
|
|
||
|
static type apply(std::pair<F, S> && p, T const& t)
|
||
|
{
|
||
|
return type(std::move(p.first), std::move(p.second), t);
|
||
|
}
|
||
|
|
||
|
static type apply(std::pair<F, S> && p, T && t)
|
||
|
{
|
||
|
return type(std::move(p.first), std::move(p.second), std::move(t));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename Is, typename Tuple, typename T>
|
||
|
struct push_back_st;
|
||
|
|
||
|
template <std::size_t ...Is, typename ...Ts, typename T>
|
||
|
struct push_back_st<std::index_sequence<Is...>, std::tuple<Ts...>, T>
|
||
|
{
|
||
|
typedef std::tuple<Ts..., T> type;
|
||
|
|
||
|
static type apply(std::tuple<Ts...> const& tup, T const& t)
|
||
|
{
|
||
|
return type(std::get<Is>(tup)..., t);
|
||
|
}
|
||
|
|
||
|
static type apply(std::tuple<Ts...> && tup, T const& t)
|
||
|
{
|
||
|
return type(std::move(std::get<Is>(tup))..., t);
|
||
|
}
|
||
|
|
||
|
static type apply(std::tuple<Ts...> && tup, T && t)
|
||
|
{
|
||
|
return type(std::move(std::get<Is>(tup))..., std::move(t));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename ...Ts, typename T>
|
||
|
struct push_back<std::tuple<Ts...>, T>
|
||
|
: push_back_st
|
||
|
<
|
||
|
std::make_index_sequence<sizeof...(Ts)>,
|
||
|
std::tuple<Ts...>,
|
||
|
T
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
|
||
|
}}} // namespace boost::geometry::tuples
|
||
|
|
||
|
#endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP
|