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