diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/sub_range.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/sub_range.hpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/boost/geometry/algorithms/detail/sub_range.hpp b/boost/geometry/algorithms/detail/sub_range.hpp new file mode 100644 index 0000000000..a68f31362a --- /dev/null +++ b/boost/geometry/algorithms/detail/sub_range.hpp @@ -0,0 +1,113 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2013, 2014. +// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. + +// 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) + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP + +#include <boost/geometry/util/range.hpp> + +namespace boost { namespace geometry { + +#ifndef DOXYGEN_NO_DETAIL + +#ifndef DOXYGEN_NO_DISPATCH +namespace detail_dispatch { + +template <typename Geometry, + typename Tag = typename geometry::tag<Geometry>::type, + bool IsMulti = boost::is_base_of<multi_tag, Tag>::value> +struct sub_range : not_implemented<Tag> +{}; + +template <typename Geometry, typename Tag> +struct sub_range<Geometry, Tag, false> +{ + typedef Geometry & return_type; + + template <typename Id> static inline + return_type apply(Geometry & geometry, Id const&) + { + return geometry; + } +}; + +template <typename Geometry> +struct sub_range<Geometry, polygon_tag, false> +{ + typedef typename geometry::ring_type<Geometry>::type & return_type; + + template <typename Id> static inline + return_type apply(Geometry & geometry, Id const& id) + { + if ( id.ring_index < 0 ) + { + return geometry::exterior_ring(geometry); + } + else + { + std::size_t ri = static_cast<std::size_t>(id.ring_index); + return range::at(geometry::interior_rings(geometry), ri); + } + } +}; + +template <typename Geometry, typename Tag> +struct sub_range<Geometry, Tag, true> +{ + typedef typename boost::range_value<Geometry>::type value_type; + typedef typename boost::mpl::if_c + < + boost::is_const<Geometry>::value, + typename boost::add_const<value_type>::type, + value_type + >::type sub_type; + + typedef detail_dispatch::sub_range<sub_type> sub_sub_range; + + // TODO: shouldn't it be return_type? + typedef typename sub_sub_range::return_type return_type; + + template <typename Id> static inline + return_type apply(Geometry & geometry, Id const& id) + { + BOOST_ASSERT(0 <= id.multi_index); + return sub_sub_range::apply(range::at(geometry, id.multi_index), id); + } +}; + +} // namespace detail_dispatch +#endif // DOXYGEN_NO_DISPATCH + +namespace detail { + +template <typename Geometry> +struct sub_range_return_type +{ + typedef typename detail_dispatch::sub_range<Geometry>::return_type type; +}; + +// This function also works for geometry::segment_identifier + +template <typename Geometry, typename Id> inline +typename sub_range_return_type<Geometry>::type +sub_range(Geometry & geometry, Id const& id) +{ + return detail_dispatch::sub_range<Geometry>::apply(geometry, id); +} + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP |