Libosmium  2.18.0
Fast and flexible C++ library for working with OpenStreetMap data
visitor.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_VISITOR_HPP
2 #define OSMIUM_VISITOR_HPP
3 
4 /*
5 
6 This file is part of Osmium (https://osmcode.org/libosmium).
7 
8 Copyright 2013-2022 Jochen Topf <jochen@topf.org> and others (see README).
9 
10 Boost Software License - Version 1.0 - August 17th, 2003
11 
12 Permission is hereby granted, free of charge, to any person or organization
13 obtaining a copy of the software and accompanying documentation covered by
14 this license (the "Software") to use, reproduce, display, distribute,
15 execute, and transmit the Software, and to prepare derivative works of the
16 Software, and to permit third-parties to whom the Software is furnished to
17 do so, all subject to the following:
18 
19 The copyright notices in the Software and this entire statement, including
20 the above license grant, this restriction and the following disclaimer,
21 must be included in all copies of the Software, in whole or in part, and
22 all derivative works of the Software, unless such copies or derivative
23 works are solely in the form of machine-executable object code generated by
24 a source language processor.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 DEALINGS IN THE SOFTWARE.
33 
34 */
35 
36 #include <osmium/fwd.hpp>
37 #include <osmium/handler.hpp>
38 #include <osmium/io/reader_iterator.hpp> // IWYU pragma: keep
39 #include <osmium/memory/buffer.hpp>
40 #include <osmium/osm.hpp>
41 #include <osmium/osm/entity.hpp>
42 #include <osmium/osm/item_type.hpp>
43 
44 #include <type_traits>
45 #include <utility>
46 
47 namespace osmium {
48 
49  namespace detail {
50 
51  template <typename T, typename U>
52  using ConstIfConst = typename std::conditional<std::is_const<T>::value, typename std::add_const<U>::type, U>::type;
53 
54  template <typename THandler, typename TItem>
55  inline void apply_item_impl(TItem& item, THandler&& handler) {
56  switch (item.type()) {
58  break;
60  handler.osm_object(static_cast<ConstIfConst<TItem, osmium::OSMObject>&>(item));
61  handler.node(static_cast<ConstIfConst<TItem, osmium::Node>&>(item));
62  break;
64  handler.osm_object(static_cast<ConstIfConst<TItem, osmium::OSMObject>&>(item));
65  handler.way(static_cast<ConstIfConst<TItem, osmium::Way>&>(item));
66  break;
68  handler.osm_object(static_cast<ConstIfConst<TItem, osmium::OSMObject>&>(item));
69  handler.relation(static_cast<ConstIfConst<TItem, osmium::Relation>&>(item));
70  break;
72  handler.osm_object(static_cast<ConstIfConst<TItem, osmium::OSMObject>&>(item));
73  handler.area(static_cast<ConstIfConst<TItem, osmium::Area>&>(item));
74  break;
76  handler.changeset(static_cast<ConstIfConst<TItem, osmium::Changeset>&>(item));
77  break;
79  handler.tag_list(static_cast<ConstIfConst<TItem, osmium::TagList>&>(item));
80  break;
82  handler.way_node_list(static_cast<ConstIfConst<TItem, osmium::WayNodeList>&>(item));
83  break;
86  handler.relation_member_list(static_cast<ConstIfConst<TItem, osmium::RelationMemberList>&>(item));
87  break;
89  handler.outer_ring(static_cast<ConstIfConst<TItem, osmium::OuterRing>&>(item));
90  break;
92  handler.inner_ring(static_cast<ConstIfConst<TItem, osmium::InnerRing>&>(item));
93  break;
95  handler.changeset_discussion(static_cast<ConstIfConst<TItem, osmium::ChangesetDiscussion>&>(item));
96  break;
97  }
98  }
99 
100  template <typename THandler>
101  inline void apply_item_impl(const osmium::OSMEntity& item, THandler&& handler) {
102  switch (item.type()) {
104  handler.osm_object(static_cast<const osmium::OSMObject&>(item));
105  handler.node(static_cast<const osmium::Node&>(item));
106  break;
108  handler.osm_object(static_cast<const osmium::OSMObject&>(item));
109  handler.way(static_cast<const osmium::Way&>(item));
110  break;
112  handler.osm_object(static_cast<const osmium::OSMObject&>(item));
113  handler.relation(static_cast<const osmium::Relation&>(item));
114  break;
116  handler.osm_object(static_cast<const osmium::OSMObject&>(item));
117  handler.area(static_cast<const osmium::Area&>(item));
118  break;
120  handler.changeset(static_cast<const osmium::Changeset&>(item));
121  break;
122  default:
123  throw osmium::unknown_type{};
124  }
125  }
126 
127  template <typename THandler>
128  inline void apply_item_impl(osmium::OSMEntity& item, THandler&& handler) {
129  switch (item.type()) {
131  handler.osm_object(static_cast<osmium::OSMObject&>(item));
132  handler.node(static_cast<osmium::Node&>(item));
133  break;
135  handler.osm_object(static_cast<osmium::OSMObject&>(item));
136  handler.way(static_cast<osmium::Way&>(item));
137  break;
139  handler.osm_object(static_cast<osmium::OSMObject&>(item));
140  handler.relation(static_cast<osmium::Relation&>(item));
141  break;
143  handler.osm_object(static_cast<osmium::OSMObject&>(item));
144  handler.area(static_cast<osmium::Area&>(item));
145  break;
147  handler.changeset(static_cast<osmium::Changeset&>(item));
148  break;
149  default:
150  throw osmium::unknown_type{};
151  }
152  }
153 
154  template <typename THandler>
155  inline void apply_item_impl(const osmium::OSMObject& item, THandler&& handler) {
156  switch (item.type()) {
158  handler.osm_object(item);
159  handler.node(static_cast<const osmium::Node&>(item));
160  break;
162  handler.osm_object(item);
163  handler.way(static_cast<const osmium::Way&>(item));
164  break;
166  handler.osm_object(item);
167  handler.relation(static_cast<const osmium::Relation&>(item));
168  break;
170  handler.osm_object(item);
171  handler.area(static_cast<const osmium::Area&>(item));
172  break;
173  default:
174  throw osmium::unknown_type{};
175  }
176  }
177 
178  template <typename THandler>
179  inline void apply_item_impl(osmium::OSMObject& item, THandler&& handler) {
180  switch (item.type()) {
182  handler.osm_object(item);
183  handler.node(static_cast<osmium::Node&>(item));
184  break;
186  handler.osm_object(item);
187  handler.way(static_cast<osmium::Way&>(item));
188  break;
190  handler.osm_object(item);
191  handler.relation(static_cast<osmium::Relation&>(item));
192  break;
194  handler.osm_object(item);
195  handler.area(static_cast<osmium::Area&>(item));
196  break;
197  default:
198  throw osmium::unknown_type{};
199  }
200  }
201 
202  template <typename TFunc>
203  struct wrapper_handler : TFunc {
204 
205  template <typename T>
206  explicit wrapper_handler(T&& func) : TFunc(std::forward<T>(func)) { // NOLINT(bugprone-forwarding-reference-overload)
207  }
208 
209  // Fallback that always matches.
210  void operator()(const osmium::memory::Item& /*item*/) const noexcept {
211  }
212 
213  // The function we are wrapping.
214  using TFunc::operator();
215 
216  void osm_object(const osmium::OSMObject& /*osm_object*/) const noexcept {
217  }
218 
219  void node(const osmium::Node& node) const {
220  operator()(node);
221  }
222 
223  // cppcheck-suppress constParameter
224  void node(osmium::Node& node) const {
225  operator()(node);
226  }
227 
228  void way(const osmium::Way& way) const {
229  operator()(way);
230  }
231 
232  // cppcheck-suppress constParameter
233  void way(osmium::Way& way) const {
234  operator()(way);
235  }
236 
237  void relation(const osmium::Relation& relation) const {
238  operator()(relation);
239  }
240 
241  // cppcheck-suppress constParameter
242  void relation(osmium::Relation& relation) const {
243  operator()(relation);
244  }
245 
246  void area(const osmium::Area& area) const {
247  operator()(area);
248  }
249 
250  // cppcheck-suppress constParameter
251  void area(osmium::Area& area) const {
252  operator()(area);
253  }
254 
255  void changeset(const osmium::Changeset& changeset) const {
256  operator()(changeset);
257  }
258 
259  // cppcheck-suppress constParameter
260  void changeset(osmium::Changeset& changeset) const {
261  operator()(changeset);
262  }
263 
264  void tag_list(const osmium::TagList& /*tag_list*/) const noexcept {
265  }
266 
267  void way_node_list(const osmium::WayNodeList& /*way_node_list*/) const noexcept {
268  }
269 
270  void relation_member_list(const osmium::RelationMemberList& /*relation_member_list*/) const noexcept {
271  }
272 
273  void outer_ring(const osmium::OuterRing& /*outer_ring*/) const noexcept {
274  }
275 
276  void inner_ring(const osmium::InnerRing& /*inner_ring*/) const noexcept {
277  }
278 
279  void changeset_discussion(const osmium::ChangesetDiscussion& /*changeset_discussion*/) const noexcept {
280  }
281 
282  void flush() const noexcept {
283  }
284 
285  }; // struct wrapper_handler
286 
287  // Is the class T derived from osmium::handler::Handler?
288  template <typename T>
290 
291  // This is already a handler, use it as it is.
292  template <typename T, typename = typename std::enable_if<is_handler<T>::value>::type>
293  T make_handler(T&& func) {
294  return std::forward<T>(func);
295  }
296 
297  // This is not a handler, but a functor. Wrap a handler around it.
298  template <typename T, typename = typename std::enable_if<!is_handler<T>::value>::type>
299  wrapper_handler<typename std::decay<T>::type> make_handler(T&& func) {
300  return wrapper_handler<typename std::decay<T>::type>(std::forward<T>(func));
301  }
302 
303  } // namespace detail
304 
305  template <typename TItem, typename... THandlers>
306  inline void apply_item(TItem& item, THandlers&&... handlers) {
307  (void)std::initializer_list<int>{
308  (detail::apply_item_impl(item, std::forward<THandlers>(handlers)), 0)...};
309  }
310 
311  template <typename... THandlers>
312  inline void apply_flush(THandlers&&... handlers) {
313  (void)std::initializer_list<int>{
314  (std::forward<THandlers>(handlers).flush(), 0)...};
315  }
316 
317  template <typename TIterator, typename... THandlers>
318  inline void apply_impl(TIterator it, TIterator end, THandlers&&... handlers) {
319  for (; it != end; ++it) {
320  apply_item(*it, handlers...);
321  }
322  apply_flush(std::forward<THandlers>(handlers)...);
323  }
324 
325  template <typename TIterator, typename... THandlers>
326  inline void apply(TIterator it, TIterator end, THandlers&&... handlers) {
327  apply_impl(it, end, detail::make_handler<THandlers>(std::forward<THandlers>(handlers))...);
328  }
329 
330  template <typename TContainer, typename... THandlers>
331  inline void apply(TContainer& c, THandlers&&... handlers) {
332  using std::begin;
333  using std::end;
334  apply(begin(c), end(c), std::forward<THandlers>(handlers)...);
335  }
336 
337  template <typename... THandlers>
338  inline void apply(const osmium::memory::Buffer& buffer, THandlers&&... handlers) {
339  apply(buffer.cbegin(), buffer.cend(), std::forward<THandlers>(handlers)...);
340  }
341 
342 } // namespace osmium
343 
344 #endif // OSMIUM_VISITOR_HPP
Definition: area.hpp:125
Definition: changeset.hpp:132
An OSM Changeset, a group of changes made by a single user over a short period of time.
Definition: changeset.hpp:148
Definition: area.hpp:80
Definition: node.hpp:48
OSMEntity is the abstract base class for the OSMObject and Changeset classes.
Definition: entity.hpp:64
Definition: object.hpp:64
Definition: area.hpp:60
Definition: relation.hpp:147
Definition: relation.hpp:161
Definition: tag.hpp:119
Definition: way.hpp:55
Definition: way.hpp:72
Definition: item.hpp:105
item_type type() const noexcept
Definition: item.hpp:171
Definition: attr.hpp:342
@ forward
Linestring has same direction as way.
InputIterator< Reader > begin(Reader &reader)
Definition: reader_iterator.hpp:43
InputIterator< Reader > end(Reader &)
Definition: reader_iterator.hpp:47
type
Definition: entity_bits.hpp:63
@ node
Definition: entity_bits.hpp:68
@ changeset
Definition: entity_bits.hpp:75
@ relation
Definition: entity_bits.hpp:70
@ area
Definition: entity_bits.hpp:72
@ way
Definition: entity_bits.hpp:69
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
void apply_item(TItem &item, THandlers &&... handlers)
Definition: visitor.hpp:306
void apply(TIterator it, TIterator end, THandlers &&... handlers)
Definition: visitor.hpp:326
void apply_flush(THandlers &&... handlers)
Definition: visitor.hpp:312
void apply_impl(TIterator it, TIterator end, THandlers &&... handlers)
Definition: visitor.hpp:318
@ relation_member_list_with_full_members
Definition: location.hpp:555
Definition: item_type.hpp:197