Libosmium  2.11.1
Fast and flexible C++ library for working with OpenStreetMap data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
attr.hpp
Go to the documentation of this file.
1 #ifndef OSMIUM_BUILDER_ATTR_HPP
2 #define OSMIUM_BUILDER_ATTR_HPP
3 
4 /*
5 
6 This file is part of Osmium (http://osmcode.org/libosmium).
7 
8 Copyright 2013-2017 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 <cstddef>
37 #include <cstdint>
38 #include <ctime>
39 #include <initializer_list>
40 #include <iterator>
41 #include <string>
42 #include <tuple>
43 #include <type_traits>
44 #include <utility>
45 
48 #include <osmium/memory/buffer.hpp>
49 #include <osmium/osm/changeset.hpp>
50 #include <osmium/osm/item_type.hpp>
51 #include <osmium/osm/location.hpp>
52 #include <osmium/osm/node.hpp>
53 #include <osmium/osm/node_ref.hpp>
54 #include <osmium/osm/object.hpp>
55 #include <osmium/osm/relation.hpp>
56 #include <osmium/osm/timestamp.hpp>
57 #include <osmium/osm/types.hpp>
58 
59 namespace osmium {
60 
61  namespace builder {
62 
63  namespace detail {
64 
65 #ifdef _MSC_VER
66  // workaround for bug in MSVC
67 
68  template <typename THandler, typename... TTypes>
69  struct is_handled_by;
70 
71  template <typename THandler>
72  struct is_handled_by<THandler> {
73  static constexpr bool value = false;
74  };
75 
76  template <typename THandler, typename T, typename... TRest>
77  struct is_handled_by<THandler, T, TRest...> {
78  static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value ||
79  is_handled_by<THandler, TRest...>::value;
80  };
81 
82  template <typename THandler, typename... TTypes>
83  struct are_all_handled_by;
84 
85  template <typename THandler, typename T>
86  struct are_all_handled_by<THandler, T> {
87  static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value;
88  };
89 
90  template <typename THandler, typename T, typename... TRest>
91  struct are_all_handled_by<THandler, T, TRest...> {
92  static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value &&
93  are_all_handled_by<THandler, TRest...>::value;
94  };
95 #else
96  // True if Predicate matches for none of the types Ts
97  template <template<typename> class Predicate, typename... Ts>
98  struct static_none_of : std::is_same<std::tuple<std::false_type, typename Predicate<Ts>::type...>,
99  std::tuple<typename Predicate<Ts>::type..., std::false_type>>
100  {};
101 
102  // True if Predicate matches for all of the types Ts
103  template <template<typename> class Predicate, typename... Ts>
104  struct static_all_of : std::is_same<std::tuple<std::true_type, typename Predicate<Ts>::type...>,
105  std::tuple<typename Predicate<Ts>::type..., std::true_type>>
106  {};
107 
108  // True if THandler is derived from the handler for at least one of the types in TTypes
109  template <typename THandler, typename... TTypes>
110  struct is_handled_by {
111  template <typename T>
112  using HasHandler = std::is_base_of<typename T::handler, THandler>;
113 
114  static constexpr bool value = !static_none_of<HasHandler, TTypes...>::value;
115  };
116 
117  // True if THandler is derived from the handlers of all the types in TTypes
118  template <typename THandler, typename... TTypes>
119  struct are_all_handled_by {
120  template <typename T>
121  using HasHandler = std::is_base_of<typename T::handler, THandler>;
122 
123  static constexpr bool value = static_all_of<HasHandler, TTypes...>::value;
124  };
125 #endif
126 
127 
128  // Wraps any type, so that we can derive from it
129  template <typename TType>
130  struct type_wrapper {
131 
132  using type = TType;
133 
134  TType value;
135 
136  constexpr explicit type_wrapper(const TType& v) :
137  value(v) {
138  }
139 
140  }; // struct type_wrapper
141 
142  // Small wrapper for begin/end iterator
143  template <typename TType>
144  struct iterator_wrapper {
145 
146  using type = TType;
147 
148  TType first;
149  TType last;
150 
151  constexpr iterator_wrapper(TType begin, TType end) :
152  first(begin),
153  last(end) {}
154 
155  constexpr TType begin() const {
156  return first;
157  }
158 
159  constexpr TType end() const {
160  return last;
161  }
162 
163  }; // struct iterator_wrapper
164 
165 
166  struct entity_handler {};
167  struct object_handler;
168  struct node_handler;
169  struct tags_handler;
170  struct nodes_handler;
171  struct members_handler;
172  struct changeset_handler;
173  struct discussion_handler;
174  struct ring_handler;
175 
176  } // namespace detail
177 
178 #define OSMIUM_ATTRIBUTE(_handler, _name, _type) \
179  struct _name : public osmium::builder::detail::type_wrapper<_type> { \
180  using handler = osmium::builder::detail::_handler;
181 
182 #define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type) \
183  OSMIUM_ATTRIBUTE(_handler, _name, _type) \
184  constexpr explicit _name(std::add_const<_type>::type& value) : \
185  type_wrapper(value) {} \
186  }
187 
188 #define OSMIUM_ATTRIBUTE_ITER(_handler, _name) \
189  template <typename TIterator> \
190  struct _name : public osmium::builder::detail::iterator_wrapper<TIterator> { \
191  using handler = osmium::builder::detail::_handler; \
192  constexpr _name(TIterator first, TIterator last) : \
193  osmium::builder::detail::iterator_wrapper<TIterator>(first, last) {} \
194  }
195 
196  namespace attr {
197 
202 
203  OSMIUM_ATTRIBUTE(object_handler, _deleted, bool)
204  constexpr explicit _deleted(bool value = true) noexcept :
205  type_wrapper(value) {}
206  };
207 
208  OSMIUM_ATTRIBUTE(object_handler, _visible, bool)
209  constexpr explicit _visible(bool value = true) noexcept :
210  type_wrapper(value) {}
211  };
212 
214  constexpr explicit _timestamp(const osmium::Timestamp& value) noexcept :
215  type_wrapper(value) {}
216  constexpr explicit _timestamp(time_t value) noexcept :
217  type_wrapper(osmium::Timestamp{value}) {}
218  constexpr explicit _timestamp(uint32_t value) noexcept :
219  type_wrapper(osmium::Timestamp{value}) {}
220  explicit _timestamp(const char* value) :
221  type_wrapper(osmium::Timestamp{value}) {}
222  explicit _timestamp(const std::string& value) :
223  type_wrapper(osmium::Timestamp{value}) {}
224  };
225 
227  constexpr explicit _location(const osmium::Location& value) noexcept :
228  type_wrapper(value) {}
229  explicit _location(double lat, double lon) :
230  type_wrapper(osmium::Location{lat, lon}) {}
231  };
232 
233  OSMIUM_ATTRIBUTE(entity_handler, _user, const char*)
234  constexpr explicit _user(const char* val) noexcept :
235  type_wrapper(val) {}
236  explicit _user(const std::string& val) noexcept :
237  type_wrapper(val.c_str()) {}
238  };
239 
240  using pair_of_cstrings = std::pair<const char* const, const char* const>;
241  using pair_of_strings = std::pair<const std::string&, const std::string&>;
242 
243  class member_type {
244 
247  const char* m_role;
248 
249  public:
250 
251  constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char* role = "") noexcept :
252  m_type(type),
253  m_ref(ref),
254  m_role(role) {
255  }
256 
257  constexpr osmium::item_type type() const noexcept {
258  return m_type;
259  }
260 
261  constexpr osmium::object_id_type ref() const noexcept {
262  return m_ref;
263  }
264 
265  constexpr const char* role() const noexcept {
266  return m_role;
267  }
268 
269  }; // class member_type
270 
272 
275  std::string m_role;
276 
277  public:
278 
280  m_type(type),
281  m_ref(ref),
282  m_role(std::move(role)) {
283  }
284 
285  osmium::item_type type() const noexcept {
286  return m_type;
287  }
288 
289  osmium::object_id_type ref() const noexcept {
290  return m_ref;
291  }
292 
293  const char* role() const noexcept {
294  return m_role.c_str();
295  }
296 
297  }; // class member_type_string
298 
299  class comment_type {
300 
303  const char* m_user;
304  const char* m_text;
305 
306  public:
307 
308  constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char* user, const char* text) noexcept :
309  m_date(date),
310  m_uid(uid),
311  m_user(user),
312  m_text(text) {
313  }
314 
315  constexpr osmium::Timestamp date() const noexcept {
316  return m_date;
317  }
318 
319  constexpr osmium::user_id_type uid() const noexcept {
320  return m_uid;
321  }
322 
323  constexpr const char* user() const noexcept {
324  return m_user;
325  }
326 
327  constexpr const char* text() const noexcept {
328  return m_text;
329  }
330 
331  }; // class comment_type
332 
333  namespace detail {
334 
335  OSMIUM_ATTRIBUTE_ITER(tags_handler, tags_from_iterator_pair);
336 
337  OSMIUM_ATTRIBUTE_ITER(nodes_handler, nodes_from_iterator_pair);
338 
339  OSMIUM_ATTRIBUTE_ITER(members_handler, members_from_iterator_pair);
340 
341  OSMIUM_ATTRIBUTE_ITER(discussion_handler, comments_from_iterator_pair);
342 
343  OSMIUM_ATTRIBUTE_ITER(ring_handler, outer_ring_from_iterator_pair);
344  OSMIUM_ATTRIBUTE_ITER(ring_handler, inner_ring_from_iterator_pair);
345 
346  } // namespace detail
347 
348  OSMIUM_ATTRIBUTE(tags_handler, _tag, pair_of_cstrings)
349  explicit _tag(const pair_of_cstrings& value) noexcept :
350  type_wrapper(value) {}
351  explicit _tag(const std::pair<const char* const, const char*>& value) :
352  type_wrapper(pair_of_cstrings{value.first, value.second}) {}
353  explicit _tag(const std::pair<const char*, const char* const>& value) :
354  type_wrapper(pair_of_cstrings{value.first, value.second}) {}
355  explicit _tag(const std::pair<const char*, const char*>& value) :
356  type_wrapper(pair_of_cstrings{value.first, value.second}) {}
357  explicit _tag(const pair_of_strings& value) :
358  type_wrapper(std::make_pair(value.first.c_str(), value.second.c_str())) {}
359  explicit _tag(const char* key, const char* val) :
360  type_wrapper(std::make_pair(key, val)) {}
361  explicit _tag(const std::string& key, const std::string& val) :
362  type_wrapper(std::make_pair(key.c_str(), val.c_str())) {}
363  };
364 
365  template <typename TTagIterator>
366  inline constexpr detail::tags_from_iterator_pair<TTagIterator> _tags(TTagIterator first, TTagIterator last) {
367  return detail::tags_from_iterator_pair<TTagIterator>(first, last);
368  }
369 
370  template <typename TContainer>
371  inline detail::tags_from_iterator_pair<typename TContainer::const_iterator> _tags(const TContainer& container) {
372  return detail::tags_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
373  }
374 
375  using tag_ilist = std::initializer_list<std::pair<const char*, const char*>>;
376  inline detail::tags_from_iterator_pair<tag_ilist::const_iterator> _tags(const tag_ilist& container) {
377  return detail::tags_from_iterator_pair<tag_ilist::const_iterator>(std::begin(container), std::end(container));
378  }
379 
380 
381 
382  OSMIUM_ATTRIBUTE(nodes_handler, _node, osmium::NodeRef)
383  constexpr explicit _node(osmium::object_id_type value) noexcept :
384  type_wrapper(NodeRef{value}) {}
385  constexpr explicit _node(const NodeRef& value) noexcept :
386  type_wrapper(value) {}
387  };
388 
389  template <typename TIdIterator>
390  inline constexpr detail::nodes_from_iterator_pair<TIdIterator> _nodes(TIdIterator first, TIdIterator last) {
391  return detail::nodes_from_iterator_pair<TIdIterator>(first, last);
392  }
393 
394  template <typename TContainer>
395  inline detail::nodes_from_iterator_pair<typename TContainer::const_iterator> _nodes(const TContainer& container) {
396  return detail::nodes_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
397  }
398 
399  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
400  inline detail::nodes_from_iterator_pair<object_id_ilist::const_iterator> _nodes(const object_id_ilist& container) {
401  return detail::nodes_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
402  }
403 
404  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
405  inline detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator> _nodes(const node_ref_ilist& container) {
406  return detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
407  }
408 
409 
410  OSMIUM_ATTRIBUTE(members_handler, _member, member_type)
411  constexpr explicit _member(const member_type& value) noexcept :
412  type_wrapper(value) {}
413  constexpr explicit _member(osmium::item_type type, osmium::object_id_type id) noexcept :
414  type_wrapper({type, id}) {}
415  constexpr explicit _member(osmium::item_type type, osmium::object_id_type id, const char* role) noexcept :
416  type_wrapper({type, id, role}) {}
417  explicit _member(osmium::item_type type, osmium::object_id_type id, const std::string& role) noexcept :
418  type_wrapper({type, id, role.c_str()}) {}
419  explicit _member(const osmium::RelationMember& member) noexcept :
420  type_wrapper({member.type(), member.ref(), member.role()}) {}
421  };
422 
423  template <typename TMemberIterator>
424  inline constexpr detail::members_from_iterator_pair<TMemberIterator> _members(TMemberIterator first, TMemberIterator last) {
425  return detail::members_from_iterator_pair<TMemberIterator>(first, last);
426  }
427 
428  template <typename TContainer>
429  inline detail::members_from_iterator_pair<typename TContainer::const_iterator> _members(const TContainer& container) {
430  return detail::members_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
431  }
432 
433  using member_ilist = std::initializer_list<member_type>;
434  inline detail::members_from_iterator_pair<member_ilist::const_iterator> _members(const member_ilist& container) {
435  return detail::members_from_iterator_pair<member_ilist::const_iterator>(std::begin(container), std::end(container));
436  }
437 
438 
439  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_changes, osmium::num_changes_type);
440  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_comments, osmium::num_comments_type);
441  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _created_at, osmium::Timestamp);
442  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _closed_at, osmium::Timestamp);
443 
444  OSMIUM_ATTRIBUTE(discussion_handler, _comment, comment_type)
445  constexpr explicit _comment(const comment_type& value) noexcept :
446  type_wrapper(value) {}
447  explicit _comment(const osmium::ChangesetComment& comment) noexcept :
448  type_wrapper({comment.date(), comment.uid(), comment.user(), comment.text()}) {}
449  };
450 
451  template <typename TCommentIterator>
452  inline constexpr detail::comments_from_iterator_pair<TCommentIterator> _comments(TCommentIterator first, TCommentIterator last) {
453  return detail::comments_from_iterator_pair<TCommentIterator>(first, last);
454  }
455 
456  template <typename TContainer>
457  inline detail::comments_from_iterator_pair<typename TContainer::const_iterator> _comments(const TContainer& container) {
458  return detail::comments_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
459  }
460 
461  using comment_ilist = std::initializer_list<comment_type>;
462  inline detail::comments_from_iterator_pair<comment_ilist::const_iterator> _comments(const comment_ilist& container) {
463  return detail::comments_from_iterator_pair<comment_ilist::const_iterator>(std::begin(container), std::end(container));
464  }
465 
466 
467  template <typename TIdIterator>
468  inline constexpr detail::outer_ring_from_iterator_pair<TIdIterator> _outer_ring(TIdIterator first, TIdIterator last) {
469  return detail::outer_ring_from_iterator_pair<TIdIterator>(first, last);
470  }
471 
472  template <typename TContainer>
473  inline detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator> _outer_ring(const TContainer& container) {
474  return detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
475  }
476 
477  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
478  inline detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator> _outer_ring(const object_id_ilist& container) {
479  return detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
480  }
481 
482  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
483  inline detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator> _outer_ring(const node_ref_ilist& container) {
484  return detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
485  }
486 
487  template <typename TIdIterator>
488  inline constexpr detail::inner_ring_from_iterator_pair<TIdIterator> _inner_ring(TIdIterator first, TIdIterator last) {
489  return detail::inner_ring_from_iterator_pair<TIdIterator>(first, last);
490  }
491 
492  template <typename TContainer>
493  inline detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator> _inner_ring(const TContainer& container) {
494  return detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator>(std::begin(container), std::end(container));
495  }
496 
497  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
498  inline detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator> _inner_ring(const object_id_ilist& container) {
499  return detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator>(std::begin(container), std::end(container));
500  }
501 
502  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
503  inline detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator> _inner_ring(const node_ref_ilist& container) {
504  return detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator>(std::begin(container), std::end(container));
505  }
506 
507 
508  } // namespace attr
509 
510 #undef OSMIUM_ATTRIBUTE_ITER
511 #undef OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR
512 #undef OSMIUM_ATTRIBUTE
513 
514  namespace detail {
515 
516  struct changeset_handler : public entity_handler {
517 
518  template <typename TDummy>
519  static void set_value(osmium::Changeset&, const TDummy&) noexcept {
520  }
521 
522  static void set_value(osmium::Changeset& changeset, attr::_cid id) noexcept {
523  changeset.set_id(id.value);
524  }
525 
526  static void set_value(osmium::Changeset& changeset, attr::_num_changes num_changes) noexcept {
527  changeset.set_num_changes(num_changes.value);
528  }
529 
530  static void set_value(osmium::Changeset& changeset, attr::_num_comments num_comments) noexcept {
531  changeset.set_num_comments(num_comments.value);
532  }
533 
534  static void set_value(osmium::Changeset& changeset, attr::_created_at created_at) noexcept {
535  changeset.set_created_at(created_at.value);
536  }
537 
538  static void set_value(osmium::Changeset& changeset, attr::_closed_at closed_at) noexcept {
539  changeset.set_closed_at(closed_at.value);
540  }
541 
542  static void set_value(osmium::Changeset& changeset, attr::_uid uid) noexcept {
543  changeset.set_uid(uid.value);
544  }
545 
546  };
547 
548  struct object_handler : public entity_handler {
549 
550  template <typename TDummy>
551  static void set_value(osmium::OSMObject&, const TDummy&) noexcept {
552  }
553 
554  static void set_value(osmium::OSMObject& object, attr::_id id) noexcept {
555  object.set_id(id.value);
556  }
557 
558  static void set_value(osmium::OSMObject& object, attr::_version version) noexcept {
559  object.set_version(version.value);
560  }
561 
562  static void set_value(osmium::OSMObject& object, attr::_visible visible) noexcept {
563  object.set_visible(visible.value);
564  }
565 
566  static void set_value(osmium::OSMObject& object, attr::_deleted deleted) noexcept {
567  object.set_deleted(deleted.value);
568  }
569 
570  static void set_value(osmium::OSMObject& object, attr::_timestamp timestamp) noexcept {
571  object.set_timestamp(timestamp.value);
572  }
573 
574  static void set_value(osmium::OSMObject& object, attr::_cid changeset) noexcept {
575  object.set_changeset(changeset.value);
576  }
577 
578  static void set_value(osmium::OSMObject& object, attr::_uid uid) noexcept {
579  object.set_uid(uid.value);
580  }
581 
582  }; // object_handler
583 
584  struct node_handler : public object_handler {
585 
587 
588  static void set_value(osmium::Node& node, attr::_location location) noexcept {
589  node.set_location(location.value);
590  }
591 
592  }; // node_handler
593 
594  template <typename THandler, typename TBuilder, typename... TArgs>
595  inline void add_basic(TBuilder& builder, const TArgs&... args) noexcept {
596  (void)std::initializer_list<int>{
597  (THandler::set_value(builder.object(), args), 0)...
598  };
599  }
600 
601  // ==============================================================
602 
603  template <typename... TArgs>
604  inline constexpr const char* get_user(const attr::_user& user, const TArgs&...) noexcept {
605  return user.value;
606  }
607 
608  inline constexpr const char* get_user() noexcept {
609  return "";
610  }
611 
612  template <typename TFirst, typename... TRest>
613  inline constexpr typename std::enable_if<!std::is_same<attr::_user, TFirst>::value, const char*>::type
614  get_user(const TFirst&, const TRest&... args) noexcept {
615  return get_user(args...);
616  }
617 
618  template <typename TBuilder, typename... TArgs>
619  inline void add_user(TBuilder& builder, const TArgs&... args) {
620  builder.set_user(get_user(args...));
621  }
622 
623  // ==============================================================
624 
625  struct tags_handler {
626 
627  template <typename TDummy>
628  static void set_value(TagListBuilder&, const TDummy&) noexcept {
629  }
630 
631  static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
632  builder.add_tag(tag.value);
633  }
634 
635  template <typename TIterator>
636  static void set_value(TagListBuilder& builder, const attr::detail::tags_from_iterator_pair<TIterator>& tags) {
637  for (const auto& tag : tags) {
638  builder.add_tag(tag);
639  }
640  }
641 
642  }; // struct tags_handler
643 
644  struct nodes_handler {
645 
646  template <typename TDummy>
647  static void set_value(WayNodeListBuilder&, const TDummy&) noexcept {
648  }
649 
650  static void set_value(WayNodeListBuilder& builder, const attr::_node& node_ref) {
651  builder.add_node_ref(node_ref.value);
652  }
653 
654  template <typename TIterator>
655  static void set_value(WayNodeListBuilder& builder, const attr::detail::nodes_from_iterator_pair<TIterator>& nodes) {
656  for (const auto& ref : nodes) {
657  builder.add_node_ref(ref);
658  }
659  }
660 
661  }; // struct nodes_handler
662 
664 
665  template <typename TDummy>
666  static void set_value(RelationMemberListBuilder&, const TDummy&) noexcept {
667  }
668 
669  static void set_value(RelationMemberListBuilder& builder, const attr::_member& member) {
670  builder.add_member(member.value.type(), member.value.ref(), member.value.role());
671  }
672 
673  template <typename TIterator>
674  static void set_value(RelationMemberListBuilder& builder, const attr::detail::members_from_iterator_pair<TIterator>& members) {
675  for (const auto& member : members) {
676  builder.add_member(member.type(), member.ref(), member.role());
677  }
678  }
679 
680  }; // struct members_handler
681 
683 
684  template <typename TDummy>
685  static void set_value(ChangesetDiscussionBuilder&, const TDummy&) noexcept {
686  }
687 
688  static void set_value(ChangesetDiscussionBuilder& builder, const attr::_comment& comment) {
689  builder.add_comment(comment.value.date(), comment.value.uid(), comment.value.user());
690  builder.add_comment_text(comment.value.text());
691  }
692 
693  template <typename TIterator>
694  static void set_value(ChangesetDiscussionBuilder& builder, const attr::detail::comments_from_iterator_pair<TIterator>& comments) {
695  for (const auto& comment : comments) {
696  builder.add_comment(comment.date(), comment.uid(), comment.user());
697  builder.add_comment_text(comment.text());
698  }
699  }
700 
701  }; // struct discussion_handler
702 
703  struct ring_handler {
704 
705  template <typename TDummy>
706  static void set_value(AreaBuilder&, const TDummy&) noexcept {
707  }
708 
709  template <typename TIterator>
710  static void set_value(AreaBuilder& parent, const attr::detail::outer_ring_from_iterator_pair<TIterator>& nodes) {
711  OuterRingBuilder builder(parent.buffer(), &parent);
712  for (const auto& ref : nodes) {
713  builder.add_node_ref(ref);
714  }
715  }
716 
717  template <typename TIterator>
718  static void set_value(AreaBuilder& parent, const attr::detail::inner_ring_from_iterator_pair<TIterator>& nodes) {
719  InnerRingBuilder builder(parent.buffer(), &parent);
720  for (const auto& ref : nodes) {
721  builder.add_node_ref(ref);
722  }
723  }
724 
725  }; // struct ring_handler
726 
727  // ==============================================================
728 
729  template <typename TBuilder, typename THandler, typename... TArgs>
730  inline typename std::enable_if<!is_handled_by<THandler, TArgs...>::value>::type
731  add_list(osmium::builder::Builder&, const TArgs&...) noexcept {
732  }
733 
734  template <typename TBuilder, typename THandler, typename... TArgs>
735  inline typename std::enable_if<is_handled_by<THandler, TArgs...>::value>::type
736  add_list(osmium::builder::Builder& parent, const TArgs&... args) {
737  TBuilder builder(parent.buffer(), &parent);
738  (void)std::initializer_list<int>{
739  (THandler::set_value(builder, args), 0)...
740  };
741  }
742 
743  struct any_node_handlers : public node_handler, public tags_handler {};
744  struct any_way_handlers : public object_handler, public tags_handler, public nodes_handler {};
746  struct any_area_handlers : public object_handler, public tags_handler, public ring_handler {};
748 
749  } // namespace detail
750 
751 
759  template <typename... TArgs>
760  inline size_t add_node(osmium::memory::Buffer& buffer, const TArgs&... args) {
761 
762  {
763  NodeBuilder builder(buffer);
764 
765  detail::add_basic<detail::node_handler>(builder, args...);
766  detail::add_user(builder, args...);
767  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
768  }
769 
770  return buffer.commit();
771  }
772 
780  template <typename... TArgs>
781  inline size_t add_way(osmium::memory::Buffer& buffer, const TArgs&... args) {
782 
783  {
784  WayBuilder builder(buffer);
785 
786  detail::add_basic<detail::object_handler>(builder, args...);
787  detail::add_user(builder, args...);
788  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
789  detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
790  }
791 
792  return buffer.commit();
793  }
794 
802  template <typename... TArgs>
803  inline size_t add_relation(osmium::memory::Buffer& buffer, const TArgs&... args) {
804 
805  {
806  RelationBuilder builder(buffer);
807 
808  detail::add_basic<detail::object_handler>(builder, args...);
809  detail::add_user(builder, args...);
810  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
811  detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
812  }
813 
814  return buffer.commit();
815  }
816 
824  template <typename... TArgs>
825  inline size_t add_changeset(osmium::memory::Buffer& buffer, const TArgs&... args) {
826 
827  {
828  ChangesetBuilder builder(buffer);
829 
830  detail::add_basic<detail::changeset_handler>(builder, args...);
831  detail::add_user(builder, args...);
832  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
833  detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
834  }
835 
836  return buffer.commit();
837  }
838 
846  template <typename... TArgs>
847  inline size_t add_area(osmium::memory::Buffer& buffer, const TArgs&... args) {
848 
849  {
850  AreaBuilder builder(buffer);
851 
852  detail::add_basic<detail::object_handler>(builder, args...);
853  detail::add_user(builder, args...);
854  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
855 
856  (void)std::initializer_list<int>{
857  (detail::ring_handler::set_value(builder, args), 0)...
858  };
859  }
860 
861  return buffer.commit();
862  }
863 
871  template <typename... TArgs>
872  inline size_t add_way_node_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
873 
874  {
875  WayNodeListBuilder builder(buffer);
876  (void)std::initializer_list<int>{
877  (detail::nodes_handler::set_value(builder, args), 0)...
878  };
879  }
880 
881  return buffer.commit();
882  }
883 
891  template <typename... TArgs>
892  inline size_t add_tag_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
893 
894  {
895  TagListBuilder builder(buffer);
896  (void)std::initializer_list<int>{
897  (detail::tags_handler::set_value(builder, args), 0)...
898  };
899  }
900 
901  return buffer.commit();
902  }
903 
904  } // namespace builder
905 
906 } // namespace osmium
907 
908 #endif // OSMIUM_BUILDER_ATTR_HPP
static void set_value(osmium::Changeset &changeset, attr::_cid id) noexcept
Definition: attr.hpp:522
Definition: attr.hpp:745
uint32_t object_version_type
Type for OSM object version number.
Definition: types.hpp:47
uint32_t user_id_type
Type for OSM user IDs.
Definition: types.hpp:49
static void set_value(ChangesetDiscussionBuilder &builder, const attr::detail::comments_from_iterator_pair< TIterator > &comments)
Definition: attr.hpp:694
constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char *user, const char *text) noexcept
Definition: attr.hpp:308
static void set_value(AreaBuilder &parent, const attr::detail::inner_ring_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:718
constexpr _node(osmium::object_id_type value) noexcept
Definition: attr.hpp:383
osmium::memory::Buffer & buffer() noexcept
Return the buffer this builder is using.
Definition: builder.hpp:209
size_t add_tag_list(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:892
Definition: attr.hpp:703
static void set_value(RelationMemberListBuilder &builder, const attr::_member &member)
Definition: attr.hpp:669
static void set_value(WayNodeListBuilder &builder, const attr::_node &node_ref)
Definition: attr.hpp:650
std::initializer_list< std::pair< const char *, const char * >> tag_ilist
Definition: attr.hpp:375
static void set_value(osmium::OSMObject &object, attr::_uid uid) noexcept
Definition: attr.hpp:578
osmium::item_type m_type
Definition: attr.hpp:273
type
Definition: entity_bits.hpp:63
std::initializer_list< member_type > member_ilist
Definition: attr.hpp:433
constexpr _location(const osmium::Location &value) noexcept
Definition: attr.hpp:227
NodeRefListBuilder< InnerRing > InnerRingBuilder
Definition: osm_object_builder.hpp:213
static void set_value(osmium::OSMObject &object, attr::_version version) noexcept
Definition: attr.hpp:558
osmium::item_type m_type
Definition: attr.hpp:245
#define OSMIUM_ATTRIBUTE(_handler, _name, _type)
Definition: attr.hpp:178
constexpr const char * user() const noexcept
Definition: attr.hpp:323
NodeRefListBuilder< WayNodeList > WayNodeListBuilder
Definition: osm_object_builder.hpp:211
constexpr detail::comments_from_iterator_pair< TCommentIterator > _comments(TCommentIterator first, TCommentIterator last)
Definition: attr.hpp:452
Definition: attr.hpp:744
item_type
Definition: item_type.hpp:43
static void set_value(RelationMemberListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:666
std::enable_if<!is_handled_by< THandler, TArgs...>::value >::type add_list(osmium::builder::Builder &, const TArgs &...) noexcept
Definition: attr.hpp:731
constexpr _user(const char *val) noexcept
Definition: attr.hpp:234
_timestamp(const std::string &value)
Definition: attr.hpp:222
Definition: reader_iterator.hpp:39
size_t add_node(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:760
static void set_value(TagListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:628
Definition: attr.hpp:516
uint32_t num_changes_type
Type for changeset num_changes.
Definition: types.hpp:51
osmium::Timestamp m_date
Definition: attr.hpp:301
static void set_value(osmium::OSMObject &object, attr::_deleted deleted) noexcept
Definition: attr.hpp:566
Definition: attr.hpp:243
Definition: changeset.hpp:59
Definition: attr.hpp:271
size_t add_area(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:847
Definition: attr.hpp:548
Definition: attr.hpp:663
static void set_value(ChangesetDiscussionBuilder &, const TDummy &) noexcept
Definition: attr.hpp:685
void add_basic(TBuilder &builder, const TArgs &...args) noexcept
Definition: attr.hpp:595
const char * role() const noexcept
Definition: attr.hpp:293
static void set_value(osmium::Changeset &changeset, attr::_uid uid) noexcept
Definition: attr.hpp:542
Definition: attr.hpp:644
static void set_value(osmium::Changeset &changeset, attr::_num_comments num_comments) noexcept
Definition: attr.hpp:530
Definition: attr.hpp:682
std::string m_role
Definition: attr.hpp:275
static void set_value(AreaBuilder &parent, const attr::detail::outer_ring_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:710
static void set_value(osmium::Changeset &changeset, attr::_created_at created_at) noexcept
Definition: attr.hpp:534
osmium::object_id_type m_ref
Definition: attr.hpp:274
Definition: attr.hpp:746
static void set_value(osmium::OSMObject &, const TDummy &) noexcept
Definition: attr.hpp:551
constexpr const char * role() const noexcept
Definition: attr.hpp:265
constexpr detail::nodes_from_iterator_pair< TIdIterator > _nodes(TIdIterator first, TIdIterator last)
Definition: attr.hpp:390
Definition: relation.hpp:57
static void set_value(osmium::OSMObject &object, attr::_timestamp timestamp) noexcept
Definition: attr.hpp:570
Namespace for everything in the Osmium library.
Definition: assembler.hpp:73
std::initializer_list< comment_type > comment_ilist
Definition: attr.hpp:461
constexpr _deleted(bool value=true) noexcept
Definition: attr.hpp:204
Definition: attr.hpp:333
OSMIUM_ATTRIBUTE_ITER(tags_handler, tags_from_iterator_pair)
uint32_t num_comments_type
Type for changeset num_comments.
Definition: types.hpp:52
constexpr osmium::user_id_type uid() const noexcept
Definition: attr.hpp:319
_tag(const pair_of_cstrings &value) noexcept
Definition: attr.hpp:349
Definition: timestamp.hpp:115
static void set_value(WayNodeListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:647
constexpr detail::inner_ring_from_iterator_pair< TIdIterator > _inner_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:488
osmium::io::InputIterator< osmium::io::Reader > end(osmium::io::Reader &)
Definition: reader_iterator.hpp:45
constexpr detail::members_from_iterator_pair< TMemberIterator > _members(TMemberIterator first, TMemberIterator last)
Definition: attr.hpp:424
osmium::object_id_type ref() const noexcept
Definition: attr.hpp:289
uint32_t changeset_id_type
Type for OSM changeset IDs.
Definition: types.hpp:48
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition: types.hpp:45
Definition: attr.hpp:743
static void set_value(ChangesetDiscussionBuilder &builder, const attr::_comment &comment)
Definition: attr.hpp:688
constexpr _comment(const comment_type &value) noexcept
Definition: attr.hpp:445
member_type_string(osmium::item_type type, osmium::object_id_type ref, std::string &&role)
Definition: attr.hpp:279
constexpr _timestamp(const osmium::Timestamp &value) noexcept
Definition: attr.hpp:214
static void set_value(TagListBuilder &builder, const attr::_tag &tag)
Definition: attr.hpp:631
Definition: location.hpp:266
constexpr detail::outer_ring_from_iterator_pair< TIdIterator > _outer_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:468
size_t add_way(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:781
constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char *role="") noexcept
Definition: attr.hpp:251
static void set_value(osmium::OSMObject &object, attr::_cid changeset) noexcept
Definition: attr.hpp:574
static void set_value(osmium::Changeset &, const TDummy &) noexcept
Definition: attr.hpp:519
std::pair< const std::string &, const std::string & > pair_of_strings
Definition: attr.hpp:241
constexpr _member(const member_type &value) noexcept
Definition: attr.hpp:411
static void set_value(osmium::Changeset &changeset, attr::_closed_at closed_at) noexcept
Definition: attr.hpp:538
size_t add_way_node_list(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:872
constexpr osmium::object_id_type ref() const noexcept
Definition: attr.hpp:261
void add_user(TBuilder &builder, const TArgs &...args)
Definition: attr.hpp:619
Definition: buffer.hpp:97
const char * m_user
Definition: attr.hpp:303
std::initializer_list< osmium::NodeRef > node_ref_ilist
Definition: attr.hpp:404
size_t add_relation(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:803
constexpr const char * get_user(const attr::_user &user, const TArgs &...) noexcept
Definition: attr.hpp:604
constexpr detail::tags_from_iterator_pair< TTagIterator > _tags(TTagIterator first, TTagIterator last)
Definition: attr.hpp:366
constexpr osmium::Timestamp date() const noexcept
Definition: attr.hpp:315
static void set_value(osmium::Node &node, attr::_location location) noexcept
Definition: attr.hpp:588
Definition: node.hpp:48
NodeRefListBuilder< OuterRing > OuterRingBuilder
Definition: osm_object_builder.hpp:212
static void set_value(osmium::Changeset &changeset, attr::_num_changes num_changes) noexcept
Definition: attr.hpp:526
osmium::object_id_type m_ref
Definition: attr.hpp:246
static void set_value(WayNodeListBuilder &builder, const attr::detail::nodes_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:655
An OSM Changeset, a group of changes made by a single user over a short period of time...
Definition: changeset.hpp:148
std::initializer_list< osmium::object_id_type > object_id_ilist
Definition: attr.hpp:399
static void set_value(osmium::OSMObject &object, attr::_visible visible) noexcept
Definition: attr.hpp:562
const char * m_role
Definition: attr.hpp:247
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _id, osmium::object_id_type)
size_t add_changeset(osmium::memory::Buffer &buffer, const TArgs &...args)
Definition: attr.hpp:825
constexpr _visible(bool value=true) noexcept
Definition: attr.hpp:209
Definition: attr.hpp:747
const char * m_text
Definition: attr.hpp:304
std::pair< const char *const, const char *const > pair_of_cstrings
Definition: attr.hpp:240
static void set_value(TagListBuilder &builder, const attr::detail::tags_from_iterator_pair< TIterator > &tags)
Definition: attr.hpp:636
Definition: node_ref.hpp:50
osmium::io::InputIterator< osmium::io::Reader > begin(osmium::io::Reader &reader)
Definition: reader_iterator.hpp:41
#define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type)
Definition: attr.hpp:182
Definition: attr.hpp:299
constexpr const char * text() const noexcept
Definition: attr.hpp:327
static void set_value(osmium::OSMObject &object, attr::_id id) noexcept
Definition: attr.hpp:554
osmium::item_type type() const noexcept
Definition: attr.hpp:285
constexpr osmium::item_type type() const noexcept
Definition: attr.hpp:257
Definition: builder.hpp:61
Definition: attr.hpp:584
Definition: object.hpp:64
osmium::user_id_type m_uid
Definition: attr.hpp:302
Definition: attr.hpp:625
size_t commit()
Definition: buffer.hpp:354
static void set_value(RelationMemberListBuilder &builder, const attr::detail::members_from_iterator_pair< TIterator > &members)
Definition: attr.hpp:674
static void set_value(AreaBuilder &, const TDummy &) noexcept
Definition: attr.hpp:706