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