// Boost.Geometry Index // // Copyright (c) 2011-2019 Adam Wulkiewicz, Lodz, Poland. // // This file was modified by Oracle on 2020. // Modifications copyright (c) 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_INDEX_INDEXABLE_HPP #define BOOST_GEOMETRY_INDEX_INDEXABLE_HPP #include #include #include #include namespace boost { namespace geometry { namespace index { namespace detail { template struct is_referencable : std::is_same < typename util::remove_cref::type, typename util::remove_cref::type > {}; template inline Indexable const& indexable_prevent_any_type(V const& ) { BOOST_GEOMETRY_STATIC_ASSERT_FALSE("Unexpected type.", V); return Indexable(); } /*! \brief The function object extracting Indexable from Value. It translates Value object to Indexable object. The default version handles Values which are Indexables. This template is also specialized for std::pair, boost::tuple and std::tuple. \tparam Value The Value type which may be translated directly to the Indexable. \tparam IsIndexable If true, the const reference to Value is returned. */ template ::value> struct indexable { BOOST_GEOMETRY_STATIC_ASSERT( (detail::is_indexable::value), "Value has to be an Indexable.", Value); /*! \brief The type of result returned by function object. */ typedef Value const& result_type; /*! \brief Return indexable extracted from the value. \param v The value. \return The indexable. */ inline result_type operator()(Value const& v) const { return v; } /*! \brief Prevent reference to temporary for types convertible to Value. */ template inline result_type operator()(V const& v) const { return indexable_prevent_any_type(v); } }; /*! \brief The function object extracting Indexable from Value. This specialization translates from std::pair. \tparam Indexable The Indexable type. \tparam Second The second type. */ template struct indexable, false> { typedef std::pair value_type; BOOST_GEOMETRY_STATIC_ASSERT( (detail::is_indexable::value), "The first type of std::pair has to be an Indexable.", Indexable); /*! \brief The type of result returned by function object. */ typedef Indexable const& result_type; /*! \brief Return indexable extracted from the value. \param v The value. \return The indexable. */ inline result_type operator()(value_type const& v) const { return v.first; } /*! \brief Return indexable extracted from compatible type different than value_type. \param v The value. \return The indexable. */ template inline result_type operator()(std::pair const& v) const { BOOST_GEOMETRY_STATIC_ASSERT( (is_referencable::value), "Unexpected type.", std::pair); return v.first; } /*! \brief Prevent reference to temporary for types convertible to Value. */ template inline result_type operator()(V const& v) const { return indexable_prevent_any_type(v); } }; /*! \brief The function object extracting Indexable from Value. This specialization translates from boost::tuple or boost::tuples::cons. \tparam Value The Value type. \tparam Indexable The Indexable type. */ template struct indexable_boost_tuple { typedef Value value_type; BOOST_GEOMETRY_STATIC_ASSERT( (detail::is_indexable::value), "The first type of boost::tuple has to be an Indexable.", Indexable); /*! \brief The type of result returned by function object. */ typedef Indexable const& result_type; /*! \brief Return indexable extracted from the value. \param v The value. \return The indexable. */ inline result_type operator()(value_type const& v) const { return boost::get<0>(v); } /*! \brief Return indexable extracted from compatible type different than value_type. \param v The value. \return The indexable. */ template inline result_type operator()(boost::tuple const& v) const { BOOST_GEOMETRY_STATIC_ASSERT( (is_referencable::value), "Unexpected type.", boost::tuple); return boost::get<0>(v); } /*! \brief Return indexable extracted from compatible type different than value_type. \param v The value. \return The indexable. */ template inline result_type operator()(boost::tuples::cons const& v) const { BOOST_GEOMETRY_STATIC_ASSERT( (is_referencable::value), "Unexpected type.", boost::tuples::cons); return boost::get<0>(v); } /*! \brief Prevent reference to temporary for types convertible to Value. */ template inline result_type operator()(V const& v) const { return indexable_prevent_any_type(v); } }; /*! \brief The function object extracting Indexable from Value. This specialization translates from boost::tuple. \tparam Indexable The Indexable type. */ template struct indexable, false> : indexable_boost_tuple < boost::tuple, Indexable > {}; /*! \brief The function object extracting Indexable from Value. This specialization translates from boost::tuples::cons. \tparam Indexable The Indexable type. */ template struct indexable, false> : indexable_boost_tuple < boost::tuples::cons, Indexable > {}; }}}} // namespace boost::geometry::index::detail #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #include namespace boost { namespace geometry { namespace index { namespace detail { /*! \brief The function object extracting Indexable from Value. This specialization translates from std::tuple. It's defined if the compiler supports tuples and variadic templates. \tparam Indexable The Indexable type. */ template struct indexable, false> { typedef std::tuple value_type; BOOST_GEOMETRY_STATIC_ASSERT( (detail::is_indexable::value), "The first type of std::tuple has to be an Indexable.", Indexable); /*! \brief The type of result returned by function object. */ typedef Indexable const& result_type; /*! \brief Return indexable extracted from the value. \param v The value. \return The indexable. */ result_type operator()(value_type const& v) const { return std::get<0>(v); } /*! \brief Return indexable extracted from compatible type different than value_type. \param v The value. \return The indexable. */ template inline result_type operator()(std::tuple const& v) const { BOOST_GEOMETRY_STATIC_ASSERT( (is_referencable::value), "Unexpected type.", std::tuple); return std::get<0>(v); } /*! \brief Prevent reference to temporary for types convertible to Value. */ template inline result_type operator()(V const& v) const { return indexable_prevent_any_type(v); } }; }}}} // namespace boost::geometry::index::detail #endif // !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) namespace boost { namespace geometry { namespace index { /*! \brief The function object extracting Indexable from Value. It translates Value object to Indexable object. By default, it can handle Values which are Indexables, std::pair, boost::tuple and std::tuple if STD tuples and variadic templates are supported. \tparam Value The Value type which may be translated directly to the Indexable. */ template struct indexable : detail::indexable { /*! \brief The type of result returned by function object. It should be const Indexable reference. */ typedef typename detail::indexable::result_type result_type; /*! \brief Return indexable extracted from the value. \param v The value. \return The indexable. */ inline result_type operator()(Value const& v) const { return detail::indexable::operator()(v); } /*! \brief Return indexable extracted from the value. Overload for types compatible with Value but different yet holding referencable Indexable, e.g. tuple containing a reference. \param v The value. \return The indexable. */ template inline result_type operator()(V const& v) const { return detail::indexable::operator()(v); } }; }}} // namespace boost::geometry::index #endif // BOOST_GEOMETRY_INDEX_INDEXABLE_HPP