diff --git a/include/boost/geometry/util/tuples.hpp b/include/boost/geometry/util/tuples.hpp index d7ff9a077..d644a05c4 100644 --- a/include/boost/geometry/util/tuples.hpp +++ b/include/boost/geometry/util/tuples.hpp @@ -13,15 +13,158 @@ #ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP #define BOOST_GEOMETRY_UTIL_TUPLES_HPP -#include +#include +#include +#include #include #include #include +#include + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES) + +#include + +#endif // C++11 + namespace boost { namespace geometry { namespace tuples { +using boost::tuples::null_type; + + +template +struct element + : boost::tuples::element +{}; + +template +struct size + : boost::tuples::length +{}; + +template +inline typename boost::tuples::access_traits + < + typename boost::tuples::element >::type + >::non_const_type +get(boost::tuples::cons & tup) +{ + return boost::tuples::get(tup); +} + +template +inline typename boost::tuples::access_traits + < + typename boost::tuples::element >::type + >::const_type +get(boost::tuples::cons const& tup) +{ + return boost::tuples::get(tup); +} + + +template +struct element > +{}; + +template +struct element<0, std::pair > +{ + typedef F type; +}; + +template +struct element<1, std::pair > +{ + typedef S type; +}; + +template +struct size > + : boost::integral_constant +{}; + +template +struct get_pair; + +template +struct get_pair<0, std::pair > +{ + typedef F type; + + static inline F& apply(std::pair & p) + { + return p.first; + } + + static inline F const& apply(std::pair const& p) + { + return p.first; + } +}; + +template +struct get_pair<1, std::pair > +{ + typedef S type; + + static inline S& apply(std::pair & p) + { + return p.second; + } + + static inline S const& apply(std::pair const& p) + { + return p.second; + } +}; + +template +inline typename get_pair >::type& +get(std::pair & p) +{ + return get_pair >::apply(p); +} + +template +inline typename get_pair >::type const& +get(std::pair const& p) +{ + return get_pair >::apply(p); +} + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES) + +template +struct element > + : std::tuple_element > +{}; + +template +struct size > + : std::tuple_size > +{}; + +template +inline typename std::tuple_element >::type& +get(std::tuple & tup) +{ + return std::get(tup); +} + +template +inline typename std::tuple_element >::type const& +get(std::tuple const& tup) +{ + return std::get(tup); +} + +#endif // C++11 + + // 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 @@ -31,12 +174,12 @@ template typename Tuple, template class UnaryPred, int I = 0, - int N = boost::tuples::length::value + int N = size::value > struct find_index_if : boost::mpl::if_c < - UnaryPred::type>::value, + UnaryPred::type>::value, boost::integral_constant, typename find_index_if::type >::type @@ -62,14 +205,14 @@ template typename Tuple, template class UnaryPred, int I = 0, - int N = boost::tuples::length::value + int N = size::value > struct find_if : boost::mpl::if_c < - UnaryPred::type>::value, - boost::tuples::element, - typename find_if + UnaryPred::type>::value, + element, + find_if >::type {}; @@ -119,27 +262,27 @@ struct exists_if template ::value> -struct push_back + size_t N = size::value> +struct push_back_bt { typedef boost::tuples::cons< - typename boost::tuples::element::type, - typename push_back::type + typename element::type, + typename push_back_bt::type > type; static type apply(Tuple const& tup, T const& t) { return type( - boost::get(tup), - push_back::apply(tup, t) + geometry::tuples::get(tup), + push_back_bt::apply(tup, t) ); } }; template -struct push_back +struct push_back_bt { typedef boost::tuples::cons type; @@ -149,6 +292,103 @@ struct push_back } }; +template +struct push_back + : push_back_bt +{}; + +template +struct push_back, T> +{ +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES) + typedef std::tuple type; +#else + typedef boost::tuple type; +#endif // C++11 + + static type apply(std::pair const& p, T const& t) + { + return type(p.first, p.second, t); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES) +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + static type apply(std::pair && p, T const& t) + { + return type(std::move(p.first), std::move(p.second), t); + } + + static type apply(std::pair && p, T && t) + { + return type(std::move(p.first), std::move(p.second), std::move(t)); + } + +#endif +#endif + +}; + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES) + +// NOTE: In C++14 std::integer_sequence and std::make_integer_sequence could be used + +template +struct int_sequence {}; + +template +struct make_int_sequence +{ + typedef typename make_int_sequence::type type; +}; + +template +struct make_int_sequence<0, Is...> +{ + typedef int_sequence type; +}; + +template +struct push_back_st; + +template +struct push_back_st, std::tuple, T> +{ + typedef std::tuple type; + + static type apply(std::tuple const& tup, T const& t) + { + return type(std::get(tup)..., t); + } + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + static type apply(std::tuple && tup, T const& t) + { + return type(std::move(std::get(tup))..., t); + } + + static type apply(std::tuple && tup, T && t) + { + return type(std::move(std::get(tup))..., std::move(t)); + } + +#endif +}; + +template +struct push_back, T> + : push_back_st + < + typename make_int_sequence::type, + std::tuple, + T + > +{}; + +#endif // C++11 + + }}} // namespace boost::geometry::tuples #endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP