1 // Boost.Geometry Index
2 //
3 // R-tree ostreaming visitor implementation
4 //
5 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
6 //
7 // This file was modified by Oracle on 2019-2020.
8 // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 //
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14
15 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
16 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
17
18 #include <iostream>
19
20 #include <boost/geometry/core/static_assert.hpp>
21
22 namespace boost { namespace geometry { namespace index { namespace detail {
23
24 namespace utilities {
25
26 namespace dispatch {
27
28 template <typename Point, size_t Dimension>
29 struct print_point
30 {
31 BOOST_STATIC_ASSERT(0 < Dimension);
32
applyboost::geometry::index::detail::utilities::dispatch::print_point33 static inline void apply(std::ostream & os, Point const& p)
34 {
35 print_point<Point, Dimension - 1>::apply(os, p);
36
37 os << ", " << geometry::get<Dimension - 1>(p);
38 }
39 };
40
41 template <typename Point>
42 struct print_point<Point, 1>
43 {
applyboost::geometry::index::detail::utilities::dispatch::print_point44 static inline void apply(std::ostream & os, Point const& p)
45 {
46 os << geometry::get<0>(p);
47 }
48 };
49
50 template <typename Box, size_t Corner, size_t Dimension>
51 struct print_corner
52 {
53 BOOST_STATIC_ASSERT(0 < Dimension);
54
applyboost::geometry::index::detail::utilities::dispatch::print_corner55 static inline void apply(std::ostream & os, Box const& b)
56 {
57 print_corner<Box, Corner, Dimension - 1>::apply(os, b);
58
59 os << ", " << geometry::get<Corner, Dimension - 1>(b);
60 }
61 };
62
63 template <typename Box, size_t Corner>
64 struct print_corner<Box, Corner, 1>
65 {
applyboost::geometry::index::detail::utilities::dispatch::print_corner66 static inline void apply(std::ostream & os, Box const& b)
67 {
68 os << geometry::get<Corner, 0>(b);
69 }
70 };
71
72 template <typename Indexable, typename Tag>
73 struct print_indexable
74 {
75 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
76 "Not implemented for this Indexable type.",
77 Indexable, Tag);
78 };
79
80 template <typename Indexable>
81 struct print_indexable<Indexable, box_tag>
82 {
83 static const size_t dimension = geometry::dimension<Indexable>::value;
84
applyboost::geometry::index::detail::utilities::dispatch::print_indexable85 static inline void apply(std::ostream &os, Indexable const& i)
86 {
87 os << '(';
88 print_corner<Indexable, min_corner, dimension>::apply(os, i);
89 os << ")x(";
90 print_corner<Indexable, max_corner, dimension>::apply(os, i);
91 os << ')';
92 }
93 };
94
95 template <typename Indexable>
96 struct print_indexable<Indexable, point_tag>
97 {
98 static const size_t dimension = geometry::dimension<Indexable>::value;
99
applyboost::geometry::index::detail::utilities::dispatch::print_indexable100 static inline void apply(std::ostream &os, Indexable const& i)
101 {
102 os << '(';
103 print_point<Indexable, dimension>::apply(os, i);
104 os << ')';
105 }
106 };
107
108 template <typename Indexable>
109 struct print_indexable<Indexable, segment_tag>
110 {
111 static const size_t dimension = geometry::dimension<Indexable>::value;
112
applyboost::geometry::index::detail::utilities::dispatch::print_indexable113 static inline void apply(std::ostream &os, Indexable const& i)
114 {
115 os << '(';
116 print_corner<Indexable, 0, dimension>::apply(os, i);
117 os << ")-(";
118 print_corner<Indexable, 1, dimension>::apply(os, i);
119 os << ')';
120 }
121 };
122
123 } // namespace dispatch
124
125 template <typename Indexable> inline
print_indexable(std::ostream & os,Indexable const & i)126 void print_indexable(std::ostream & os, Indexable const& i)
127 {
128 dispatch::print_indexable<
129 Indexable,
130 typename tag<Indexable>::type
131 >::apply(os, i);
132 }
133
134 } // namespace utilities
135
136 namespace rtree { namespace utilities {
137
138 namespace visitors {
139
140 template <typename MembersHolder>
141 struct print
142 : public MembersHolder::visitor_const
143 {
144 typedef typename MembersHolder::translator_type translator_type;
145
146 typedef typename MembersHolder::internal_node internal_node;
147 typedef typename MembersHolder::leaf leaf;
148
printboost::geometry::index::detail::rtree::utilities::visitors::print149 inline print(std::ostream & o, translator_type const& t)
150 : os(o), tr(t), level(0)
151 {}
152
operator ()boost::geometry::index::detail::rtree::utilities::visitors::print153 inline void operator()(internal_node const& n)
154 {
155 typedef typename rtree::elements_type<internal_node>::type elements_type;
156 elements_type const& elements = rtree::elements(n);
157
158 spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << elements.size() << " @:" << &n << '\n';
159
160 for (typename elements_type::const_iterator it = elements.begin();
161 it != elements.end(); ++it)
162 {
163 spaces(level);
164 detail::utilities::print_indexable(os, it->first);
165 os << " ->" << it->second << '\n';
166 }
167
168 size_t level_backup = level;
169 ++level;
170
171 for (typename elements_type::const_iterator it = elements.begin();
172 it != elements.end(); ++it)
173 {
174 rtree::apply_visitor(*this, *it->second);
175 }
176
177 level = level_backup;
178 }
179
operator ()boost::geometry::index::detail::rtree::utilities::visitors::print180 inline void operator()(leaf const& n)
181 {
182 typedef typename rtree::elements_type<leaf>::type elements_type;
183 elements_type const& elements = rtree::elements(n);
184
185 spaces(level) << "LEAF - L:" << level << " V:" << elements.size() << " @:" << &n << '\n';
186 for (typename elements_type::const_iterator it = elements.begin();
187 it != elements.end(); ++it)
188 {
189 spaces(level);
190 detail::utilities::print_indexable(os, tr(*it));
191 os << '\n';
192 }
193 }
194
spacesboost::geometry::index::detail::rtree::utilities::visitors::print195 inline std::ostream & spaces(size_t level)
196 {
197 for ( size_t i = 0 ; i < 2 * level ; ++i )
198 os << ' ';
199 return os;
200 }
201
202 std::ostream & os;
203 translator_type const& tr;
204
205 size_t level;
206 };
207
208 } // namespace visitors
209
210 template <typename Rtree> inline
print(std::ostream & os,Rtree const & tree)211 void print(std::ostream & os, Rtree const& tree)
212 {
213 typedef utilities::view<Rtree> RTV;
214 RTV rtv(tree);
215
216 visitors::print<
217 typename RTV::members_holder
218 > print_v(os, rtv.translator());
219 rtv.apply_visitor(print_v);
220 }
221
222 }} // namespace rtree::utilities
223
224 }}}} // namespace boost::geometry::index::detail
225
226 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_PRINT_HPP
227