summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/sub_range.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/sub_range.hpp')
-rw-r--r--boost/geometry/algorithms/detail/sub_range.hpp113
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