]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | ||
5 | // This file was modified by Oracle on 2013, 2014. | |
6 | // Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. | |
7 | ||
8 | // Use, modification and distribution is subject to the Boost Software License, | |
9 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
10 | // http://www.boost.org/LICENSE_1_0.txt) | |
11 | ||
12 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
13 | ||
14 | #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP | |
15 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP | |
16 | ||
17 | #include <boost/mpl/if.hpp> | |
18 | ||
19 | #include <boost/geometry/core/assert.hpp> | |
20 | #include <boost/geometry/util/range.hpp> | |
21 | ||
22 | namespace boost { namespace geometry { | |
23 | ||
24 | #ifndef DOXYGEN_NO_DETAIL | |
25 | ||
26 | #ifndef DOXYGEN_NO_DISPATCH | |
27 | namespace detail_dispatch { | |
28 | ||
29 | template <typename Geometry, | |
30 | typename Tag = typename geometry::tag<Geometry>::type, | |
31 | bool IsMulti = boost::is_base_of<multi_tag, Tag>::value> | |
32 | struct sub_range : not_implemented<Tag> | |
33 | {}; | |
34 | ||
35 | template <typename Geometry, typename Tag> | |
36 | struct sub_range<Geometry, Tag, false> | |
37 | { | |
38 | typedef Geometry & return_type; | |
39 | ||
40 | template <typename Id> static inline | |
41 | return_type apply(Geometry & geometry, Id const&) | |
42 | { | |
43 | return geometry; | |
44 | } | |
45 | }; | |
46 | ||
47 | template <typename Geometry> | |
48 | struct sub_range<Geometry, polygon_tag, false> | |
49 | { | |
50 | typedef typename geometry::ring_return_type<Geometry>::type return_type; | |
51 | ||
52 | template <typename Id> static inline | |
53 | return_type apply(Geometry & geometry, Id const& id) | |
54 | { | |
55 | if ( id.ring_index < 0 ) | |
56 | { | |
57 | return geometry::exterior_ring(geometry); | |
58 | } | |
59 | else | |
60 | { | |
61 | typedef typename boost::range_size | |
62 | < | |
63 | typename geometry::interior_type<Geometry>::type | |
64 | >::type size_type; | |
65 | size_type const ri = static_cast<size_type>(id.ring_index); | |
66 | return range::at(geometry::interior_rings(geometry), ri); | |
67 | } | |
68 | } | |
69 | }; | |
70 | ||
71 | template <typename Geometry, typename Tag> | |
72 | struct sub_range<Geometry, Tag, true> | |
73 | { | |
74 | typedef typename boost::range_value<Geometry>::type value_type; | |
75 | typedef typename boost::mpl::if_c | |
76 | < | |
77 | boost::is_const<Geometry>::value, | |
78 | typename boost::add_const<value_type>::type, | |
79 | value_type | |
80 | >::type sub_type; | |
81 | ||
82 | typedef detail_dispatch::sub_range<sub_type> sub_sub_range; | |
83 | ||
84 | // TODO: shouldn't it be return_type? | |
85 | typedef typename sub_sub_range::return_type return_type; | |
86 | ||
87 | template <typename Id> static inline | |
88 | return_type apply(Geometry & geometry, Id const& id) | |
89 | { | |
90 | BOOST_GEOMETRY_ASSERT(0 <= id.multi_index); | |
91 | typedef typename boost::range_size<Geometry>::type size_type; | |
92 | size_type const mi = static_cast<size_type>(id.multi_index); | |
93 | return sub_sub_range::apply(range::at(geometry, mi), id); | |
94 | } | |
95 | }; | |
96 | ||
97 | } // namespace detail_dispatch | |
98 | #endif // DOXYGEN_NO_DISPATCH | |
99 | ||
100 | namespace detail { | |
101 | ||
102 | template <typename Geometry> | |
103 | struct sub_range_return_type | |
104 | { | |
105 | typedef typename detail_dispatch::sub_range<Geometry>::return_type type; | |
106 | }; | |
107 | ||
108 | // This function also works for geometry::segment_identifier | |
109 | ||
110 | template <typename Geometry, typename Id> inline | |
111 | typename sub_range_return_type<Geometry>::type | |
112 | sub_range(Geometry & geometry, Id const& id) | |
113 | { | |
114 | return detail_dispatch::sub_range<Geometry>::apply(geometry, id); | |
115 | } | |
116 | ||
117 | template <typename Geometry, typename Id> inline | |
118 | typename sub_range_return_type<Geometry const>::type | |
119 | sub_range(Geometry const& geometry, Id const& id) | |
120 | { | |
121 | return detail_dispatch::sub_range<Geometry const>::apply(geometry, id); | |
122 | } | |
123 | ||
124 | } // namespace detail | |
125 | #endif // DOXYGEN_NO_DETAIL | |
126 | ||
127 | }} // namespace boost::geometry | |
128 | ||
129 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP |