Libosmium  2.15.0
Fast and flexible C++ library for working with OpenStreetMap data
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 (https://osmcode.org/libosmium).
7 
8 Copyright 2013-2018 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 
38 #include <osmium/memory/buffer.hpp>
39 #include <osmium/osm/changeset.hpp>
40 #include <osmium/osm/item_type.hpp>
41 #include <osmium/osm/location.hpp>
42 #include <osmium/osm/node.hpp>
43 #include <osmium/osm/node_ref.hpp>
44 #include <osmium/osm/object.hpp>
45 #include <osmium/osm/relation.hpp>
46 #include <osmium/osm/timestamp.hpp>
47 #include <osmium/osm/types.hpp>
48 
49 #include <cstddef>
50 #include <cstdint>
51 #include <ctime>
52 #include <initializer_list>
53 #include <iterator>
54 #include <string>
55 #include <tuple>
56 #include <type_traits>
57 #include <utility>
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 
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 {first, last};
368  }
369 
370  template <typename TContainer>
371  inline detail::tags_from_iterator_pair<typename TContainer::const_iterator> _tags(const TContainer& container) {
372  using std::begin;
373  using std::end;
374  return {begin(container), end(container)};
375  }
376 
377  using tag_ilist = std::initializer_list<std::pair<const char*, const char*>>;
378  inline detail::tags_from_iterator_pair<tag_ilist::const_iterator> _tags(const tag_ilist& container) {
379  using std::begin;
380  using std::end;
381  return {begin(container), end(container)};
382  }
383 
384 
385 
386  OSMIUM_ATTRIBUTE(nodes_handler, _node, osmium::NodeRef)
387  constexpr explicit _node(osmium::object_id_type value) noexcept :
388  type_wrapper(NodeRef{value}) {}
389  constexpr explicit _node(const NodeRef& value) noexcept :
390  type_wrapper(value) {}
391  };
392 
393  template <typename TIdIterator>
394  inline constexpr detail::nodes_from_iterator_pair<TIdIterator> _nodes(TIdIterator first, TIdIterator last) {
395  return {first, last};
396  }
397 
398  template <typename TContainer>
399  inline detail::nodes_from_iterator_pair<typename TContainer::const_iterator> _nodes(const TContainer& container) {
400  using std::begin;
401  using std::end;
402  return {begin(container), end(container)};
403  }
404 
405  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
406  inline detail::nodes_from_iterator_pair<object_id_ilist::const_iterator> _nodes(const object_id_ilist& container) {
407  using std::begin;
408  using std::end;
409  return {begin(container), end(container)};
410  }
411 
412  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
413  inline detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator> _nodes(const node_ref_ilist& container) {
414  using std::begin;
415  using std::end;
416  return {begin(container), end(container)};
417  }
418 
419 
420  OSMIUM_ATTRIBUTE(members_handler, _member, member_type)
421  constexpr explicit _member(const member_type& value) noexcept :
422  type_wrapper(value) {}
423  constexpr explicit _member(osmium::item_type type, osmium::object_id_type id) noexcept :
424  type_wrapper({type, id}) {}
425  constexpr explicit _member(osmium::item_type type, osmium::object_id_type id, const char* role) noexcept :
426  type_wrapper({type, id, role}) {}
427  explicit _member(osmium::item_type type, osmium::object_id_type id, const std::string& role) noexcept :
428  type_wrapper({type, id, role.c_str()}) {}
429  explicit _member(const osmium::RelationMember& member) noexcept :
430  type_wrapper({member.type(), member.ref(), member.role()}) {}
431  };
432 
433  template <typename TMemberIterator>
434  inline constexpr detail::members_from_iterator_pair<TMemberIterator> _members(TMemberIterator first, TMemberIterator last) {
435  return {first, last};
436  }
437 
438  template <typename TContainer>
439  inline detail::members_from_iterator_pair<typename TContainer::const_iterator> _members(const TContainer& container) {
440  using std::begin;
441  using std::end;
442  return {begin(container), end(container)};
443  }
444 
445  using member_ilist = std::initializer_list<member_type>;
446  inline detail::members_from_iterator_pair<member_ilist::const_iterator> _members(const member_ilist& container) {
447  using std::begin;
448  using std::end;
449  return {begin(container), end(container)};
450  }
451 
452 
453  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_changes, osmium::num_changes_type);
454  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_comments, osmium::num_comments_type);
455  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _created_at, osmium::Timestamp);
456  OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _closed_at, osmium::Timestamp);
457 
458  OSMIUM_ATTRIBUTE(discussion_handler, _comment, comment_type)
459  constexpr explicit _comment(const comment_type& value) noexcept :
460  type_wrapper(value) {}
461  explicit _comment(const osmium::ChangesetComment& comment) noexcept :
462  type_wrapper({comment.date(), comment.uid(), comment.user(), comment.text()}) {}
463  };
464 
465  template <typename TCommentIterator>
466  inline constexpr detail::comments_from_iterator_pair<TCommentIterator> _comments(TCommentIterator first, TCommentIterator last) {
467  return {first, last};
468  }
469 
470  template <typename TContainer>
471  inline detail::comments_from_iterator_pair<typename TContainer::const_iterator> _comments(const TContainer& container) {
472  using std::begin;
473  using std::end;
474  return {begin(container), end(container)};
475  }
476 
477  using comment_ilist = std::initializer_list<comment_type>;
478  inline detail::comments_from_iterator_pair<comment_ilist::const_iterator> _comments(const comment_ilist& container) {
479  using std::begin;
480  using std::end;
481  return {begin(container), end(container)};
482  }
483 
484 
485  template <typename TIdIterator>
486  inline constexpr detail::outer_ring_from_iterator_pair<TIdIterator> _outer_ring(TIdIterator first, TIdIterator last) {
487  return {first, last};
488  }
489 
490  template <typename TContainer>
491  inline detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator> _outer_ring(const TContainer& container) {
492  using std::begin;
493  using std::end;
494  return {begin(container), end(container)};
495  }
496 
497  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
498  inline detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator> _outer_ring(const object_id_ilist& container) {
499  using std::begin;
500  using std::end;
501  return {begin(container), end(container)};
502  }
503 
504  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
505  inline detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator> _outer_ring(const node_ref_ilist& container) {
506  using std::begin;
507  using std::end;
508  return {begin(container), end(container)};
509  }
510 
511  template <typename TIdIterator>
512  inline constexpr detail::inner_ring_from_iterator_pair<TIdIterator> _inner_ring(TIdIterator first, TIdIterator last) {
513  return {first, last};
514  }
515 
516  template <typename TContainer>
517  inline detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator> _inner_ring(const TContainer& container) {
518  using std::begin;
519  using std::end;
520  return {begin(container), end(container)};
521  }
522 
523  using object_id_ilist = std::initializer_list<osmium::object_id_type>;
524  inline detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator> _inner_ring(const object_id_ilist& container) {
525  using std::begin;
526  using std::end;
527  return {begin(container), end(container)};
528  }
529 
530  using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
531  inline detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator> _inner_ring(const node_ref_ilist& container) {
532  using std::begin;
533  using std::end;
534  return {begin(container), end(container)};
535  }
536 
537 
538  } // namespace attr
539 
540 #undef OSMIUM_ATTRIBUTE_ITER
541 #undef OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR
542 #undef OSMIUM_ATTRIBUTE
543 
544  namespace detail {
545 
546  struct changeset_handler : public entity_handler {
547 
548  template <typename TDummy>
549  static void set_value(osmium::Changeset& /*changeset*/, const TDummy& /*dummy*/) noexcept {
550  }
551 
552  static void set_value(osmium::Changeset& changeset, attr::_cid id) noexcept {
553  changeset.set_id(id.value);
554  }
555 
556  static void set_value(osmium::Changeset& changeset, attr::_num_changes num_changes) noexcept {
557  changeset.set_num_changes(num_changes.value);
558  }
559 
560  static void set_value(osmium::Changeset& changeset, attr::_num_comments num_comments) noexcept {
561  changeset.set_num_comments(num_comments.value);
562  }
563 
564  static void set_value(osmium::Changeset& changeset, attr::_created_at created_at) noexcept {
565  changeset.set_created_at(created_at.value);
566  }
567 
568  static void set_value(osmium::Changeset& changeset, attr::_closed_at closed_at) noexcept {
569  changeset.set_closed_at(closed_at.value);
570  }
571 
572  static void set_value(osmium::Changeset& changeset, attr::_uid uid) noexcept {
573  changeset.set_uid(uid.value);
574  }
575 
576  };
577 
578  struct object_handler : public entity_handler {
579 
580  template <typename TDummy>
581  static void set_value(osmium::OSMObject& /*object*/, const TDummy& /*dummy*/) noexcept {
582  }
583 
584  static void set_value(osmium::OSMObject& object, attr::_id id) noexcept {
585  object.set_id(id.value);
586  }
587 
588  static void set_value(osmium::OSMObject& object, attr::_version version) noexcept {
589  object.set_version(version.value);
590  }
591 
592  static void set_value(osmium::OSMObject& object, attr::_visible visible) noexcept {
593  object.set_visible(visible.value);
594  }
595 
596  static void set_value(osmium::OSMObject& object, attr::_deleted deleted) noexcept {
597  object.set_deleted(deleted.value);
598  }
599 
600  static void set_value(osmium::OSMObject& object, attr::_timestamp timestamp) noexcept {
601  object.set_timestamp(timestamp.value);
602  }
603 
604  static void set_value(osmium::OSMObject& object, attr::_cid changeset) noexcept {
605  object.set_changeset(changeset.value);
606  }
607 
608  static void set_value(osmium::OSMObject& object, attr::_uid uid) noexcept {
609  object.set_uid(uid.value);
610  }
611 
612  }; // object_handler
613 
614  struct node_handler : public object_handler {
615 
616  using object_handler::set_value;
617 
618  static void set_value(osmium::Node& node, attr::_location location) noexcept {
619  node.set_location(location.value);
620  }
621 
622  }; // node_handler
623 
624  template <typename THandler, typename TBuilder, typename... TArgs>
625  inline void add_basic(TBuilder& builder, const TArgs&... args) noexcept {
626  (void)std::initializer_list<int>{
627  (THandler::set_value(builder.object(), args), 0)...
628  };
629  }
630 
631  // ==============================================================
632 
633  template <typename... TArgs>
634  inline constexpr const char* get_user(const attr::_user& user, const TArgs&... /*args*/) noexcept {
635  return user.value;
636  }
637 
638  inline constexpr const char* get_user() noexcept {
639  return "";
640  }
641 
642  template <typename TFirst, typename... TRest>
643  inline constexpr typename std::enable_if<!std::is_same<attr::_user, TFirst>::value, const char*>::type
644  get_user(const TFirst& /*first*/, const TRest&... args) noexcept {
645  return get_user(args...);
646  }
647 
648  template <typename TBuilder, typename... TArgs>
649  inline void add_user(TBuilder& builder, const TArgs&... args) {
650  builder.set_user(get_user(args...));
651  }
652 
653  // ==============================================================
654 
655  struct tags_handler {
656 
657  template <typename TDummy>
658  static void set_value(TagListBuilder& /*tlb*/, const TDummy& /*dummy*/) noexcept {
659  }
660 
661  static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
662  builder.add_tag(tag.value);
663  }
664 
665  template <typename TIterator>
666  static void set_value(TagListBuilder& builder, const attr::detail::tags_from_iterator_pair<TIterator>& tags) {
667  for (const auto& tag : tags) {
668  builder.add_tag(tag);
669  }
670  }
671 
672  }; // struct tags_handler
673 
674  struct nodes_handler {
675 
676  template <typename TDummy>
677  static void set_value(WayNodeListBuilder& /*wnlb*/, const TDummy& /*dummy*/) noexcept {
678  }
679 
680  static void set_value(WayNodeListBuilder& builder, const attr::_node& node_ref) {
681  builder.add_node_ref(node_ref.value);
682  }
683 
684  template <typename TIterator>
685  static void set_value(WayNodeListBuilder& builder, const attr::detail::nodes_from_iterator_pair<TIterator>& nodes) {
686  for (const auto& ref : nodes) {
687  builder.add_node_ref(ref);
688  }
689  }
690 
691  }; // struct nodes_handler
692 
694 
695  template <typename TDummy>
696  static void set_value(RelationMemberListBuilder& /*rmlb*/, const TDummy& /*dummy*/) noexcept {
697  }
698 
699  static void set_value(RelationMemberListBuilder& builder, const attr::_member& member) {
700  builder.add_member(member.value.type(), member.value.ref(), member.value.role());
701  }
702 
703  template <typename TIterator>
704  static void set_value(RelationMemberListBuilder& builder, const attr::detail::members_from_iterator_pair<TIterator>& members) {
705  for (const auto& member : members) {
706  builder.add_member(member.type(), member.ref(), member.role());
707  }
708  }
709 
710  }; // struct members_handler
711 
713 
714  template <typename TDummy>
715  static void set_value(ChangesetDiscussionBuilder& /*cdb*/, const TDummy& /*dummy*/) noexcept {
716  }
717 
718  static void set_value(ChangesetDiscussionBuilder& builder, const attr::_comment& comment) {
719  builder.add_comment(comment.value.date(), comment.value.uid(), comment.value.user());
720  builder.add_comment_text(comment.value.text());
721  }
722 
723  template <typename TIterator>
724  static void set_value(ChangesetDiscussionBuilder& builder, const attr::detail::comments_from_iterator_pair<TIterator>& comments) {
725  for (const auto& comment : comments) {
726  builder.add_comment(comment.date(), comment.uid(), comment.user());
727  builder.add_comment_text(comment.text());
728  }
729  }
730 
731  }; // struct discussion_handler
732 
733  struct ring_handler {
734 
735  template <typename TDummy>
736  static void set_value(AreaBuilder& /*ab*/, const TDummy& /*dummy*/) noexcept {
737  }
738 
739  template <typename TIterator>
740  static void set_value(AreaBuilder& parent, const attr::detail::outer_ring_from_iterator_pair<TIterator>& nodes) {
741  OuterRingBuilder builder(parent.buffer(), &parent);
742  for (const auto& ref : nodes) {
743  builder.add_node_ref(ref);
744  }
745  }
746 
747  template <typename TIterator>
748  static void set_value(AreaBuilder& parent, const attr::detail::inner_ring_from_iterator_pair<TIterator>& nodes) {
749  InnerRingBuilder builder(parent.buffer(), &parent);
750  for (const auto& ref : nodes) {
751  builder.add_node_ref(ref);
752  }
753  }
754 
755  }; // struct ring_handler
756 
757  // ==============================================================
758 
759  template <typename TBuilder, typename THandler, typename... TArgs>
760  inline typename std::enable_if<!is_handled_by<THandler, TArgs...>::value>::type
761  add_list(osmium::builder::Builder& /*parent*/, const TArgs&... /*args*/) noexcept {
762  }
763 
764  template <typename TBuilder, typename THandler, typename... TArgs>
765  inline typename std::enable_if<is_handled_by<THandler, TArgs...>::value>::type
766  add_list(osmium::builder::Builder& parent, const TArgs&... args) {
767  TBuilder builder{parent.buffer(), &parent};
768  (void)std::initializer_list<int>{
769  (THandler::set_value(builder, args), 0)...
770  };
771  }
772 
773  struct any_node_handlers : public node_handler, public tags_handler {};
774  struct any_way_handlers : public object_handler, public tags_handler, public nodes_handler {};
776  struct any_area_handlers : public object_handler, public tags_handler, public ring_handler {};
778 
779  } // namespace detail
780 
781 
789  template <typename... TArgs>
790  inline size_t add_node(osmium::memory::Buffer& buffer, const TArgs&... args) {
791 
792  {
793  NodeBuilder builder{buffer};
794 
795  detail::add_basic<detail::node_handler>(builder, args...);
796  detail::add_user(builder, args...);
797  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
798  }
799 
800  return buffer.commit();
801  }
802 
810  template <typename... TArgs>
811  inline size_t add_way(osmium::memory::Buffer& buffer, const TArgs&... args) {
812 
813  {
814  WayBuilder builder{buffer};
815 
816  detail::add_basic<detail::object_handler>(builder, args...);
817  detail::add_user(builder, args...);
818  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
819  detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
820  }
821 
822  return buffer.commit();
823  }
824 
832  template <typename... TArgs>
833  inline size_t add_relation(osmium::memory::Buffer& buffer, const TArgs&... args) {
834 
835  {
836  RelationBuilder builder{buffer};
837 
838  detail::add_basic<detail::object_handler>(builder, args...);
839  detail::add_user(builder, args...);
840  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
841  detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
842  }
843 
844  return buffer.commit();
845  }
846 
854  template <typename... TArgs>
855  inline size_t add_changeset(osmium::memory::Buffer& buffer, const TArgs&... args) {
856 
857  {
858  ChangesetBuilder builder{buffer};
859 
860  detail::add_basic<detail::changeset_handler>(builder, args...);
861  detail::add_user(builder, args...);
862  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
863  detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
864  }
865 
866  return buffer.commit();
867  }
868 
876  template <typename... TArgs>
877  inline size_t add_area(osmium::memory::Buffer& buffer, const TArgs&... args) {
878 
879  {
880  AreaBuilder builder{buffer};
881 
882  detail::add_basic<detail::object_handler>(builder, args...);
883  detail::add_user(builder, args...);
884  detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
885 
886  (void)std::initializer_list<int>{
887  (detail::ring_handler::set_value(builder, args), 0)...
888  };
889  }
890 
891  return buffer.commit();
892  }
893 
901  template <typename... TArgs>
902  inline size_t add_way_node_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
903 
904  {
905  WayNodeListBuilder builder{buffer};
906  (void)std::initializer_list<int>{
907  (detail::nodes_handler::set_value(builder, args), 0)...
908  };
909  }
910 
911  return buffer.commit();
912  }
913 
921  template <typename... TArgs>
922  inline size_t add_tag_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
923 
924  {
925  TagListBuilder builder{buffer};
926  (void)std::initializer_list<int>{
927  (detail::tags_handler::set_value(builder, args), 0)...
928  };
929  }
930 
931  return buffer.commit();
932  }
933 
934  } // namespace builder
935 
936 } // namespace osmium
937 
938 #endif // OSMIUM_BUILDER_ATTR_HPP
static void set_value(osmium::Changeset &changeset, attr::_cid id) noexcept
Definition: attr.hpp:552
Definition: attr.hpp:775
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:724
std::size_t commit()
Definition: buffer.hpp:468
size_t add_way(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:811
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:748
constexpr _node(osmium::object_id_type value) noexcept
Definition: attr.hpp:387
osmium::memory::Buffer & buffer() noexcept
Return the buffer this builder is using.
Definition: builder.hpp:207
Definition: attr.hpp:733
static void set_value(RelationMemberListBuilder &builder, const attr::_member &member)
Definition: attr.hpp:699
static void set_value(WayNodeListBuilder &builder, const attr::_node &node_ref)
Definition: attr.hpp:680
static void set_value(osmium::OSMObject &object, attr::_uid uid) noexcept
Definition: attr.hpp:608
osmium::item_type m_type
Definition: attr.hpp:273
type
Definition: entity_bits.hpp:63
size_t add_changeset(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:855
std::initializer_list< member_type > member_ilist
Definition: attr.hpp:445
constexpr _location(const osmium::Location &value) noexcept
Definition: attr.hpp:227
NodeRefListBuilder< InnerRing > InnerRingBuilder
Definition: osm_object_builder.hpp:227
static void set_value(osmium::OSMObject &object, attr::_version version) noexcept
Definition: attr.hpp:588
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:225
constexpr detail::comments_from_iterator_pair< TCommentIterator > _comments(TCommentIterator first, TCommentIterator last)
Definition: attr.hpp:466
Definition: attr.hpp:774
item_type
Definition: item_type.hpp:43
InputIterator< Reader > end(Reader &)
Definition: reader_iterator.hpp:47
static void set_value(RelationMemberListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:696
size_t add_node(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:790
constexpr _user(const char *val) noexcept
Definition: attr.hpp:234
_timestamp(const std::string &value)
Definition: attr.hpp:222
Definition: location.hpp:554
static void set_value(TagListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:658
Definition: attr.hpp:546
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:596
size_t add_way_node_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:902
size_t add_tag_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:922
Definition: attr.hpp:243
Definition: changeset.hpp:59
Definition: attr.hpp:271
Definition: attr.hpp:578
Definition: attr.hpp:693
static void set_value(ChangesetDiscussionBuilder &, const TDummy &) noexcept
Definition: attr.hpp:715
const char * role() const noexcept
Definition: attr.hpp:293
static void set_value(osmium::Changeset &changeset, attr::_uid uid) noexcept
Definition: attr.hpp:572
Definition: attr.hpp:674
static void set_value(osmium::Changeset &changeset, attr::_num_comments num_comments) noexcept
Definition: attr.hpp:560
Definition: attr.hpp:712
void add_basic(TBuilder &builder, const TArgs &... args) noexcept
Definition: attr.hpp:625
std::string m_role
Definition: attr.hpp:275
InputIterator< Reader > begin(Reader &reader)
Definition: reader_iterator.hpp:43
static void set_value(AreaBuilder &parent, const attr::detail::outer_ring_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:740
static void set_value(osmium::Changeset &changeset, attr::_created_at created_at) noexcept
Definition: attr.hpp:564
osmium::object_id_type m_ref
Definition: attr.hpp:274
Definition: attr.hpp:776
static void set_value(osmium::OSMObject &, const TDummy &) noexcept
Definition: attr.hpp:581
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:394
Definition: relation.hpp:57
static void set_value(osmium::OSMObject &object, attr::_timestamp timestamp) noexcept
Definition: attr.hpp:600
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
std::initializer_list< comment_type > comment_ilist
Definition: attr.hpp:477
constexpr _deleted(bool value=true) noexcept
Definition: attr.hpp:204
Definition: attr.hpp:333
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:145
static void set_value(WayNodeListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:677
constexpr detail::inner_ring_from_iterator_pair< TIdIterator > _inner_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:512
constexpr detail::members_from_iterator_pair< TMemberIterator > _members(TMemberIterator first, TMemberIterator last)
Definition: attr.hpp:434
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:773
std::initializer_list< std::pair< const char *, const char * > > tag_ilist
Definition: attr.hpp:377
static void set_value(ChangesetDiscussionBuilder &builder, const attr::_comment &comment)
Definition: attr.hpp:718
constexpr _comment(const comment_type &value) noexcept
Definition: attr.hpp:459
member_type_string(osmium::item_type type, osmium::object_id_type ref, std::string &&role)
Definition: attr.hpp:279
void add_user(TBuilder &builder, const TArgs &... args)
Definition: attr.hpp:649
constexpr _timestamp(const osmium::Timestamp &value) noexcept
Definition: attr.hpp:214
static void set_value(TagListBuilder &builder, const attr::_tag &tag)
Definition: attr.hpp:661
Definition: location.hpp:275
constexpr detail::outer_ring_from_iterator_pair< TIdIterator > _outer_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:486
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:604
static void set_value(osmium::Changeset &, const TDummy &) noexcept
Definition: attr.hpp:549
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:421
static void set_value(osmium::Changeset &changeset, attr::_closed_at closed_at) noexcept
Definition: attr.hpp:568
#define OSMIUM_ATTRIBUTE_ITER(_handler, _name)
Definition: attr.hpp:188
constexpr osmium::object_id_type ref() const noexcept
Definition: attr.hpp:261
Definition: buffer.hpp:97
const char * m_user
Definition: attr.hpp:303
std::initializer_list< osmium::NodeRef > node_ref_ilist
Definition: attr.hpp:412
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:618
Definition: node.hpp:48
NodeRefListBuilder< OuterRing > OuterRingBuilder
Definition: osm_object_builder.hpp:226
static void set_value(osmium::Changeset &changeset, attr::_num_changes num_changes) noexcept
Definition: attr.hpp:556
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:685
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:405
static void set_value(osmium::OSMObject &object, attr::_visible visible) noexcept
Definition: attr.hpp:592
const char * m_role
Definition: attr.hpp:247
constexpr _visible(bool value=true) noexcept
Definition: attr.hpp:209
Definition: attr.hpp:777
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:666
Definition: node_ref.hpp:50
size_t add_area(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:877
std::enable_if< is_handled_by< THandler, TArgs... >::value >::type add_list(osmium::builder::Builder &parent, const TArgs &... args)
Definition: attr.hpp:766
#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:584
osmium::item_type type() const noexcept
Definition: attr.hpp:285
constexpr osmium::item_type type() const noexcept
Definition: attr.hpp:257
Definition: builder.hpp:57
size_t add_relation(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:833
Definition: attr.hpp:614
constexpr std::enable_if<!std::is_same< attr::_user, TFirst >::value, const char * >::type get_user(const TFirst &, const TRest &... args) noexcept
Definition: attr.hpp:644
Definition: object.hpp:64
osmium::user_id_type m_uid
Definition: attr.hpp:302
Definition: attr.hpp:655
static void set_value(RelationMemberListBuilder &builder, const attr::detail::members_from_iterator_pair< TIterator > &members)
Definition: attr.hpp:704
static void set_value(AreaBuilder &, const TDummy &) noexcept
Definition: attr.hpp:736