Libosmium  2.20.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
6This file is part of Osmium (https://osmcode.org/libosmium).
7
8Copyright 2013-2023 Jochen Topf <jochen@topf.org> and others (see README).
9
10Boost Software License - Version 1.0 - August 17th, 2003
11
12Permission is hereby granted, free of charge, to any person or organization
13obtaining a copy of the software and accompanying documentation covered by
14this license (the "Software") to use, reproduce, display, distribute,
15execute, and transmit the Software, and to prepare derivative works of the
16Software, and to permit third-parties to whom the Software is furnished to
17do so, all subject to the following:
18
19The copyright notices in the Software and this entire statement, including
20the above license grant, this restriction and the following disclaimer,
21must be included in all copies of the Software, in whole or in part, and
22all derivative works of the Software, unless such copies or derivative
23works are solely in the form of machine-executable object code generated by
24a source language processor.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32DEALINGS IN THE SOFTWARE.
33
34*/
35
42#include <osmium/osm/node.hpp>
44#include <osmium/osm/object.hpp>
47#include <osmium/osm/types.hpp>
49
50#include <cstddef>
51#include <cstdint>
52#include <ctime>
53#include <initializer_list>
54#include <iterator>
55#include <string>
56#include <tuple>
57#include <type_traits>
58#include <utility>
59
60namespace osmium {
61
62 namespace builder {
63
64 namespace detail {
65
66#ifdef _MSC_VER
67 // workaround for bug in MSVC
68
69 template <typename THandler, typename... TTypes>
70 struct is_handled_by;
71
72 template <typename THandler>
73 struct is_handled_by<THandler> {
74 static constexpr bool value = false;
75 };
76
77 template <typename THandler, typename T, typename... TRest>
78 struct is_handled_by<THandler, T, TRest...> {
79 static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value ||
80 is_handled_by<THandler, TRest...>::value;
81 };
82
83 template <typename THandler, typename... TTypes>
84 struct are_all_handled_by;
85
86 template <typename THandler, typename T>
87 struct are_all_handled_by<THandler, T> {
88 static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value;
89 };
90
91 template <typename THandler, typename T, typename... TRest>
92 struct are_all_handled_by<THandler, T, TRest...> {
93 static constexpr bool value = std::is_base_of<typename T::handler, THandler>::value &&
94 are_all_handled_by<THandler, TRest...>::value;
95 };
96#else
97 // True if Predicate matches for none of the types Ts
98 template <template <typename> class Predicate, typename... Ts>
99 struct static_none_of : std::is_same<std::tuple<std::false_type, typename Predicate<Ts>::type...>,
100 std::tuple<typename Predicate<Ts>::type..., std::false_type>>
101 {};
102
103 // True if Predicate matches for all of the types Ts
104 template <template <typename> class Predicate, typename... Ts>
105 struct static_all_of : std::is_same<std::tuple<std::true_type, typename Predicate<Ts>::type...>,
106 std::tuple<typename Predicate<Ts>::type..., std::true_type>>
107 {};
108
109 // True if THandler is derived from the handler for at least one of the types in TTypes
110 template <typename THandler, typename... TTypes>
111 struct is_handled_by {
112 template <typename T>
113 using HasHandler = std::is_base_of<typename T::handler, THandler>;
114
115 static constexpr bool value = !static_none_of<HasHandler, TTypes...>::value;
116 };
117
118 // True if THandler is derived from the handlers of all the types in TTypes
119 template <typename THandler, typename... TTypes>
120 struct are_all_handled_by {
121 template <typename T>
122 using HasHandler = std::is_base_of<typename T::handler, THandler>;
123
124 static constexpr bool value = static_all_of<HasHandler, TTypes...>::value;
125 };
126#endif
127
128
129 // Wraps any type, so that we can derive from it
130 template <typename TType>
131 struct type_wrapper {
132
133 using type = TType;
134
135 TType value;
136
137 constexpr explicit type_wrapper(const TType& v) :
138 value(v) {
139 }
140
141 }; // struct type_wrapper
142
143 // Small wrapper for begin/end iterator
144 template <typename TType>
145 struct iterator_wrapper {
146
147 using type = TType;
148
149 TType first;
150 TType last;
151
152 constexpr iterator_wrapper(TType begin, TType end) :
153 first(begin),
154 last(end) {}
155
156 constexpr TType begin() const {
157 return first;
158 }
159
160 constexpr TType end() const {
161 return last;
162 }
163
164 }; // struct iterator_wrapper
165
166
167 struct entity_handler {};
168 struct object_handler;
169 struct node_handler;
170 struct tags_handler;
171 struct nodes_handler;
172 struct members_handler;
173 struct changeset_handler;
174 struct discussion_handler;
175 struct ring_handler;
176
177 } // namespace detail
178
179#define OSMIUM_ATTRIBUTE(_handler, _name, _type) \
180 struct _name : public osmium::builder::detail::type_wrapper<_type> { \
181 using handler = osmium::builder::detail::_handler;
182
183#define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type) \
184 OSMIUM_ATTRIBUTE(_handler, _name, _type) \
185 constexpr explicit _name(std::add_const<_type>::type& value) : \
186 type_wrapper(value) {} \
187 }
188
189#define OSMIUM_ATTRIBUTE_ITER(_handler, _name) \
190 template <typename TIterator> \
191 struct _name : public osmium::builder::detail::iterator_wrapper<TIterator> { \
192 using handler = osmium::builder::detail::_handler; \
193 constexpr _name(TIterator first, TIterator last) : \
194 osmium::builder::detail::iterator_wrapper<TIterator>(first, last) {} \
195 }
196
197 namespace attr {
198
203
204 OSMIUM_ATTRIBUTE(object_handler, _deleted, bool)
205 constexpr explicit _deleted(bool value = true) noexcept :
206 type_wrapper(value) {}
207 };
208
209 OSMIUM_ATTRIBUTE(object_handler, _visible, bool)
210 constexpr explicit _visible(bool value = true) noexcept :
211 type_wrapper(value) {}
212 };
213
215 constexpr explicit _timestamp(const osmium::Timestamp& value) noexcept :
216 type_wrapper(value) {}
217 constexpr explicit _timestamp(time_t value) noexcept :
218 type_wrapper(osmium::Timestamp{value}) {}
219 constexpr explicit _timestamp(uint32_t value) noexcept :
220 type_wrapper(osmium::Timestamp{value}) {}
221 explicit _timestamp(const char* value) :
222 type_wrapper(osmium::Timestamp{value}) {}
223 explicit _timestamp(const std::string& value) :
224 type_wrapper(osmium::Timestamp{value}) {}
225 };
226
228 constexpr explicit _location(const osmium::Location& value) noexcept :
229 type_wrapper(value) {}
230 explicit _location(double lon, double lat) :
231 type_wrapper(osmium::Location{lon, lat}) {}
232 };
233
234 OSMIUM_ATTRIBUTE(entity_handler, _user, const char*)
235 constexpr explicit _user(const char* val) noexcept :
236 type_wrapper(val) {}
237 explicit _user(const std::string& val) noexcept :
238 type_wrapper(val.c_str()) {}
239 };
240
241 using pair_of_cstrings = std::pair<const char* const, const char* const>;
242 using pair_of_strings = std::pair<const std::string&, const std::string&>;
243
245
248 const char* m_role;
249
250 public:
251
252 constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char* role = "") noexcept :
253 m_type(type),
254 m_ref(ref),
255 m_role(role) {
256 }
257
258 member_type(char type, osmium::object_id_type ref, const char* role = "") noexcept :
260 }
261
262 constexpr osmium::item_type type() const noexcept {
263 return m_type;
264 }
265
266 constexpr osmium::object_id_type ref() const noexcept {
267 return m_ref;
268 }
269
270 constexpr const char* role() const noexcept {
271 return m_role;
272 }
273
274 }; // class member_type
275
277
280 std::string m_role;
281
282 public:
283
285 m_type(type),
286 m_ref(ref),
287 m_role(std::move(role)) {
288 }
289
290 member_type_string(char type, osmium::object_id_type ref, std::string&& role) noexcept :
292 }
293
294 osmium::item_type type() const noexcept {
295 return m_type;
296 }
297
298 osmium::object_id_type ref() const noexcept {
299 return m_ref;
300 }
301
302 const char* role() const noexcept {
303 return m_role.c_str();
304 }
305
306 }; // class member_type_string
307
309
312 const char* m_user;
313 const char* m_text;
314
315 public:
316
317 constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char* user, const char* text) noexcept :
318 m_date(date),
319 m_uid(uid),
320 m_user(user),
321 m_text(text) {
322 }
323
324 constexpr osmium::Timestamp date() const noexcept {
325 return m_date;
326 }
327
328 constexpr osmium::user_id_type uid() const noexcept {
329 return m_uid;
330 }
331
332 constexpr const char* user() const noexcept {
333 return m_user;
334 }
335
336 constexpr const char* text() const noexcept {
337 return m_text;
338 }
339
340 }; // class comment_type
341
342 namespace detail {
343
344 OSMIUM_ATTRIBUTE_ITER(tags_handler, tags_from_iterator_pair);
345
346 OSMIUM_ATTRIBUTE_ITER(nodes_handler, nodes_from_iterator_pair);
347
348 OSMIUM_ATTRIBUTE_ITER(members_handler, members_from_iterator_pair);
349
350 OSMIUM_ATTRIBUTE_ITER(discussion_handler, comments_from_iterator_pair);
351
352 OSMIUM_ATTRIBUTE_ITER(ring_handler, outer_ring_from_iterator_pair);
353 OSMIUM_ATTRIBUTE_ITER(ring_handler, inner_ring_from_iterator_pair);
354
355 } // namespace detail
356
358 explicit _tag(const pair_of_cstrings& value) noexcept :
359 type_wrapper(value) {}
360 explicit _tag(const std::pair<const char* const, const char*>& value) :
361 type_wrapper(pair_of_cstrings{value.first, value.second}) {}
362 explicit _tag(const std::pair<const char*, const char* const>& value) :
363 type_wrapper(pair_of_cstrings{value.first, value.second}) {}
364 explicit _tag(const std::pair<const char*, const char*>& value) :
365 type_wrapper(pair_of_cstrings{value.first, value.second}) {}
366 explicit _tag(const pair_of_strings& value) :
367 type_wrapper(std::make_pair(value.first.c_str(), value.second.c_str())) {}
368 explicit _tag(const char* key, const char* val) :
369 type_wrapper(std::make_pair(key, val)) {}
370 explicit _tag(const std::string& key, const std::string& val) :
371 type_wrapper(std::make_pair(key.c_str(), val.c_str())) {}
372 explicit _tag(const char* const key_value) :
373 type_wrapper(pair_of_cstrings{key_value, nullptr}) {}
374 explicit _tag(const std::string& key_value) :
375 type_wrapper(pair_of_cstrings{key_value.c_str(), nullptr}) {}
376 };
377
378 OSMIUM_ATTRIBUTE(tags_handler, _t, const char*)
379 explicit _t(const char *tags) :
380 type_wrapper(tags) {}
381 };
382
383 template <typename TTagIterator>
384 inline constexpr detail::tags_from_iterator_pair<TTagIterator> _tags(TTagIterator first, TTagIterator last) {
385 return {first, last};
386 }
387
388 template <typename TContainer>
389 inline detail::tags_from_iterator_pair<typename TContainer::const_iterator> _tags(const TContainer& container) {
390 using std::begin;
391 using std::end;
392 return {begin(container), end(container)};
393 }
394
395 using tag_ilist = std::initializer_list<std::pair<const char*, const char*>>;
396 inline detail::tags_from_iterator_pair<tag_ilist::const_iterator> _tags(const tag_ilist& container) {
397 using std::begin;
398 using std::end;
399 return {begin(container), end(container)};
400 }
401
402
403
404 OSMIUM_ATTRIBUTE(nodes_handler, _node, osmium::NodeRef)
405 constexpr explicit _node(osmium::object_id_type value) noexcept :
406 type_wrapper(NodeRef{value}) {}
407 constexpr explicit _node(const NodeRef& value) noexcept :
408 type_wrapper(value) {}
409 };
410
411 template <typename TIdIterator>
412 inline constexpr detail::nodes_from_iterator_pair<TIdIterator> _nodes(TIdIterator first, TIdIterator last) {
413 return {first, last};
414 }
415
416 template <typename TContainer>
417 inline detail::nodes_from_iterator_pair<typename TContainer::const_iterator> _nodes(const TContainer& container) {
418 using std::begin;
419 using std::end;
420 return {begin(container), end(container)};
421 }
422
423 using object_id_ilist = std::initializer_list<osmium::object_id_type>;
424 inline detail::nodes_from_iterator_pair<object_id_ilist::const_iterator> _nodes(const object_id_ilist& container) {
425 using std::begin;
426 using std::end;
427 return {begin(container), end(container)};
428 }
429
430 using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
431 inline detail::nodes_from_iterator_pair<node_ref_ilist::const_iterator> _nodes(const node_ref_ilist& container) {
432 using std::begin;
433 using std::end;
434 return {begin(container), end(container)};
435 }
436
437
438 OSMIUM_ATTRIBUTE(members_handler, _member, member_type)
439 constexpr explicit _member(const member_type& value) noexcept :
440 type_wrapper(value) {}
441 constexpr explicit _member(osmium::item_type type, osmium::object_id_type id) noexcept :
442 type_wrapper({type, id}) {}
443 constexpr explicit _member(osmium::item_type type, osmium::object_id_type id, const char* role) noexcept :
444 type_wrapper({type, id, role}) {}
445 explicit _member(osmium::item_type type, osmium::object_id_type id, const std::string& role) noexcept :
446 type_wrapper({type, id, role.c_str()}) {}
447 explicit _member(const osmium::RelationMember& member) noexcept :
448 type_wrapper({member.type(), member.ref(), member.role()}) {}
449 };
450
451 template <typename TMemberIterator>
452 inline constexpr detail::members_from_iterator_pair<TMemberIterator> _members(TMemberIterator first, TMemberIterator last) {
453 return {first, last};
454 }
455
456 template <typename TContainer>
457 inline detail::members_from_iterator_pair<typename TContainer::const_iterator> _members(const TContainer& container) {
458 using std::begin;
459 using std::end;
460 return {begin(container), end(container)};
461 }
462
463 using member_ilist = std::initializer_list<member_type>;
464 inline detail::members_from_iterator_pair<member_ilist::const_iterator> _members(const member_ilist& container) {
465 using std::begin;
466 using std::end;
467 return {begin(container), end(container)};
468 }
469
470
473 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _created_at, osmium::Timestamp);
475
476 OSMIUM_ATTRIBUTE(discussion_handler, _comment, comment_type)
477 constexpr explicit _comment(const comment_type& value) noexcept :
478 type_wrapper(value) {}
479 explicit _comment(const osmium::ChangesetComment& comment) noexcept :
480 type_wrapper({comment.date(), comment.uid(), comment.user(), comment.text()}) {}
481 };
482
483 template <typename TCommentIterator>
484 inline constexpr detail::comments_from_iterator_pair<TCommentIterator> _comments(TCommentIterator first, TCommentIterator last) {
485 return {first, last};
486 }
487
488 template <typename TContainer>
489 inline detail::comments_from_iterator_pair<typename TContainer::const_iterator> _comments(const TContainer& container) {
490 using std::begin;
491 using std::end;
492 return {begin(container), end(container)};
493 }
494
495 using comment_ilist = std::initializer_list<comment_type>;
496 inline detail::comments_from_iterator_pair<comment_ilist::const_iterator> _comments(const comment_ilist& container) {
497 using std::begin;
498 using std::end;
499 return {begin(container), end(container)};
500 }
501
502
503 template <typename TIdIterator>
504 inline constexpr detail::outer_ring_from_iterator_pair<TIdIterator> _outer_ring(TIdIterator first, TIdIterator last) {
505 return {first, last};
506 }
507
508 template <typename TContainer>
509 inline detail::outer_ring_from_iterator_pair<typename TContainer::const_iterator> _outer_ring(const TContainer& container) {
510 using std::begin;
511 using std::end;
512 return {begin(container), end(container)};
513 }
514
515 using object_id_ilist = std::initializer_list<osmium::object_id_type>;
516 inline detail::outer_ring_from_iterator_pair<object_id_ilist::const_iterator> _outer_ring(const object_id_ilist& container) {
517 using std::begin;
518 using std::end;
519 return {begin(container), end(container)};
520 }
521
522 using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
523 inline detail::outer_ring_from_iterator_pair<node_ref_ilist::const_iterator> _outer_ring(const node_ref_ilist& container) {
524 using std::begin;
525 using std::end;
526 return {begin(container), end(container)};
527 }
528
529 template <typename TIdIterator>
530 inline constexpr detail::inner_ring_from_iterator_pair<TIdIterator> _inner_ring(TIdIterator first, TIdIterator last) {
531 return {first, last};
532 }
533
534 template <typename TContainer>
535 inline detail::inner_ring_from_iterator_pair<typename TContainer::const_iterator> _inner_ring(const TContainer& container) {
536 using std::begin;
537 using std::end;
538 return {begin(container), end(container)};
539 }
540
541 using object_id_ilist = std::initializer_list<osmium::object_id_type>;
542 inline detail::inner_ring_from_iterator_pair<object_id_ilist::const_iterator> _inner_ring(const object_id_ilist& container) {
543 using std::begin;
544 using std::end;
545 return {begin(container), end(container)};
546 }
547
548 using node_ref_ilist = std::initializer_list<osmium::NodeRef>;
549 inline detail::inner_ring_from_iterator_pair<node_ref_ilist::const_iterator> _inner_ring(const node_ref_ilist& container) {
550 using std::begin;
551 using std::end;
552 return {begin(container), end(container)};
553 }
554
555
556 } // namespace attr
557
558#undef OSMIUM_ATTRIBUTE_ITER
559#undef OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR
560#undef OSMIUM_ATTRIBUTE
561
562 namespace detail {
563
564 struct changeset_handler : public entity_handler {
565
566 template <typename TDummy>
567 static void set_value(osmium::Changeset& /*changeset*/, const TDummy& /*dummy*/) noexcept {
568 }
569
570 static void set_value(osmium::Changeset& changeset, attr::_cid id) noexcept {
571 changeset.set_id(id.value);
572 }
573
574 static void set_value(osmium::Changeset& changeset, attr::_num_changes num_changes) noexcept {
575 changeset.set_num_changes(num_changes.value);
576 }
577
578 static void set_value(osmium::Changeset& changeset, attr::_num_comments num_comments) noexcept {
579 changeset.set_num_comments(num_comments.value);
580 }
581
582 static void set_value(osmium::Changeset& changeset, attr::_created_at created_at) noexcept {
583 changeset.set_created_at(created_at.value);
584 }
585
586 static void set_value(osmium::Changeset& changeset, attr::_closed_at closed_at) noexcept {
587 changeset.set_closed_at(closed_at.value);
588 }
589
590 static void set_value(osmium::Changeset& changeset, attr::_uid uid) noexcept {
591 changeset.set_uid(uid.value);
592 }
593
594 };
595
596 struct object_handler : public entity_handler {
597
598 template <typename TDummy>
599 static void set_value(osmium::OSMObject& /*object*/, const TDummy& /*dummy*/) noexcept {
600 }
601
602 static void set_value(osmium::OSMObject& object, attr::_id id) noexcept {
603 object.set_id(id.value);
604 }
605
606 static void set_value(osmium::OSMObject& object, attr::_version version) noexcept {
607 object.set_version(version.value);
608 }
609
610 static void set_value(osmium::OSMObject& object, attr::_visible visible) noexcept {
611 object.set_visible(visible.value);
612 }
613
614 static void set_value(osmium::OSMObject& object, attr::_deleted deleted) noexcept {
615 object.set_deleted(deleted.value);
616 }
617
618 static void set_value(osmium::OSMObject& object, attr::_timestamp timestamp) noexcept {
619 object.set_timestamp(timestamp.value);
620 }
621
622 static void set_value(osmium::OSMObject& object, attr::_cid changeset) noexcept {
623 object.set_changeset(changeset.value);
624 }
625
626 static void set_value(osmium::OSMObject& object, attr::_uid uid) noexcept {
627 object.set_uid(uid.value);
628 }
629
630 }; // object_handler
631
632 struct node_handler : public object_handler {
633
635
636 static void set_value(osmium::Node& node, attr::_location location) noexcept {
637 node.set_location(location.value);
638 }
639
640 }; // node_handler
641
642 template <typename THandler, typename TBuilder, typename... TArgs>
643 inline void add_basic(TBuilder& builder, const TArgs&... args) noexcept {
644 (void)std::initializer_list<int>{
645 (THandler::set_value(builder.object(), args), 0)...
646 };
647 }
648
649 // ==============================================================
650
651 template <typename... TArgs>
652 inline constexpr const char* get_user(const attr::_user& user, const TArgs&... /*args*/) noexcept {
653 return user.value;
654 }
655
656 inline constexpr const char* get_user() noexcept {
657 return "";
658 }
659
660 template <typename TFirst, typename... TRest>
661 inline constexpr typename std::enable_if<!std::is_same<attr::_user, TFirst>::value, const char*>::type
662 get_user(const TFirst& /*first*/, const TRest&... args) noexcept {
663 return get_user(args...);
664 }
665
666 template <typename TBuilder, typename... TArgs>
667 inline void add_user(TBuilder& builder, const TArgs&... args) {
668 builder.set_user(get_user(args...));
669 }
670
671 // ==============================================================
672
674
675 template <typename TDummy>
676 static void set_value(TagListBuilder& /*tlb*/, const TDummy& /*dummy*/) noexcept {
677 }
678
679 static void set_value(TagListBuilder& builder, const attr::_tag& tag) {
680 if (tag.value.second != nullptr) {
681 builder.add_tag(tag.value);
682 return;
683 }
684 const char* key = tag.value.first;
685 const char* const equal_sign = std::strchr(key, '=');
686 if (!equal_sign) {
687 builder.add_tag(key, "");
688 return;
689 }
690 const char* value = equal_sign + 1;
691 builder.add_tag(key, equal_sign - key,
692 value, std::strlen(value));
693 }
694
695 template <typename TIterator>
696 static void set_value(TagListBuilder& builder, const attr::detail::tags_from_iterator_pair<TIterator>& tags) {
697 for (const auto& tag : tags) {
698 builder.add_tag(tag);
699 }
700 }
701
702 static void set_value(TagListBuilder& builder, const attr::_t& tags) {
703 const auto taglist = osmium::split_string(tags.value, ',', true);
704 for (const auto& tag : taglist) {
705 const std::size_t pos = tag.find_first_of('=');
706 if (pos == std::string::npos) {
707 builder.add_tag(tag, "");
708 } else {
709 const char* value = tag.c_str() + pos + 1;
710 builder.add_tag(tag.c_str(), pos,
711 value, tag.size() - pos - 1);
712 }
713
714 }
715 }
716
717 }; // struct tags_handler
718
720
721 template <typename TDummy>
722 static void set_value(WayNodeListBuilder& /*wnlb*/, const TDummy& /*dummy*/) noexcept {
723 }
724
725 static void set_value(WayNodeListBuilder& builder, const attr::_node& node_ref) {
726 builder.add_node_ref(node_ref.value);
727 }
728
729 template <typename TIterator>
730 static void set_value(WayNodeListBuilder& builder, const attr::detail::nodes_from_iterator_pair<TIterator>& nodes) {
731 for (const auto& ref : nodes) {
732 builder.add_node_ref(ref);
733 }
734 }
735
736 }; // struct nodes_handler
737
739
740 template <typename TDummy>
741 static void set_value(RelationMemberListBuilder& /*rmlb*/, const TDummy& /*dummy*/) noexcept {
742 }
743
744 static void set_value(RelationMemberListBuilder& builder, const attr::_member& member) {
745 builder.add_member(member.value.type(), member.value.ref(), member.value.role());
746 }
747
748 template <typename TIterator>
749 static void set_value(RelationMemberListBuilder& builder, const attr::detail::members_from_iterator_pair<TIterator>& members) {
750 for (const auto& member : members) {
751 builder.add_member(member.type(), member.ref(), member.role());
752 }
753 }
754
755 }; // struct members_handler
756
758
759 template <typename TDummy>
760 static void set_value(ChangesetDiscussionBuilder& /*cdb*/, const TDummy& /*dummy*/) noexcept {
761 }
762
763 static void set_value(ChangesetDiscussionBuilder& builder, const attr::_comment& comment) {
764 builder.add_comment(comment.value.date(), comment.value.uid(), comment.value.user());
765 builder.add_comment_text(comment.value.text());
766 }
767
768 template <typename TIterator>
769 static void set_value(ChangesetDiscussionBuilder& builder, const attr::detail::comments_from_iterator_pair<TIterator>& comments) {
770 for (const auto& comment : comments) {
771 builder.add_comment(comment.date(), comment.uid(), comment.user());
772 builder.add_comment_text(comment.text());
773 }
774 }
775
776 }; // struct discussion_handler
777
779
780 template <typename TDummy>
781 static void set_value(AreaBuilder& /*ab*/, const TDummy& /*dummy*/) noexcept {
782 }
783
784 template <typename TIterator>
785 static void set_value(AreaBuilder& parent, const attr::detail::outer_ring_from_iterator_pair<TIterator>& nodes) {
786 OuterRingBuilder builder(parent.buffer(), &parent);
787 for (const auto& ref : nodes) {
788 builder.add_node_ref(ref);
789 }
790 }
791
792 template <typename TIterator>
793 static void set_value(AreaBuilder& parent, const attr::detail::inner_ring_from_iterator_pair<TIterator>& nodes) {
794 InnerRingBuilder builder(parent.buffer(), &parent);
795 for (const auto& ref : nodes) {
796 builder.add_node_ref(ref);
797 }
798 }
799
800 }; // struct ring_handler
801
802 // ==============================================================
803
804 template <typename TBuilder, typename THandler, typename... TArgs>
805 inline typename std::enable_if<!is_handled_by<THandler, TArgs...>::value>::type
806 add_list(osmium::builder::Builder& /*parent*/, const TArgs&... /*args*/) noexcept {
807 }
808
809 template <typename TBuilder, typename THandler, typename... TArgs>
810 inline typename std::enable_if<is_handled_by<THandler, TArgs...>::value>::type
811 add_list(osmium::builder::Builder& parent, const TArgs&... args) {
812 TBuilder builder{parent.buffer(), &parent};
813 (void)std::initializer_list<int>{
814 (THandler::set_value(builder, args), 0)...
815 };
816 }
817
818 struct any_node_handlers : public node_handler, public tags_handler {};
819 struct any_way_handlers : public object_handler, public tags_handler, public nodes_handler {};
821 struct any_area_handlers : public object_handler, public tags_handler, public ring_handler {};
823
824 } // namespace detail
825
826
834 template <typename... TArgs>
835 inline size_t add_node(osmium::memory::Buffer& buffer, const TArgs&... args) {
836
837 {
838 NodeBuilder builder{buffer};
839
840 detail::add_basic<detail::node_handler>(builder, args...);
841 detail::add_user(builder, args...);
842 detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
843 }
844
845 return buffer.commit();
846 }
847
855 template <typename... TArgs>
856 inline size_t add_way(osmium::memory::Buffer& buffer, const TArgs&... args) {
857
858 {
859 WayBuilder builder{buffer};
860
861 detail::add_basic<detail::object_handler>(builder, args...);
862 detail::add_user(builder, args...);
863 detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
864 detail::add_list<WayNodeListBuilder, detail::nodes_handler>(builder, args...);
865 }
866
867 return buffer.commit();
868 }
869
877 template <typename... TArgs>
878 inline size_t add_relation(osmium::memory::Buffer& buffer, const TArgs&... args) {
879
880 {
881 RelationBuilder builder{buffer};
882
883 detail::add_basic<detail::object_handler>(builder, args...);
884 detail::add_user(builder, args...);
885 detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
886 detail::add_list<RelationMemberListBuilder, detail::members_handler>(builder, args...);
887 }
888
889 return buffer.commit();
890 }
891
899 template <typename... TArgs>
900 inline size_t add_changeset(osmium::memory::Buffer& buffer, const TArgs&... args) {
901
902 {
903 ChangesetBuilder builder{buffer};
904
905 detail::add_basic<detail::changeset_handler>(builder, args...);
906 detail::add_user(builder, args...);
907 detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
908 detail::add_list<ChangesetDiscussionBuilder, detail::discussion_handler>(builder, args...);
909 }
910
911 return buffer.commit();
912 }
913
921 template <typename... TArgs>
922 inline size_t add_area(osmium::memory::Buffer& buffer, const TArgs&... args) {
923
924 {
925 AreaBuilder builder{buffer};
926
927 detail::add_basic<detail::object_handler>(builder, args...);
928 detail::add_user(builder, args...);
929 detail::add_list<TagListBuilder, detail::tags_handler>(builder, args...);
930
931 (void)std::initializer_list<int>{
932 (detail::ring_handler::set_value(builder, args), 0)...
933 };
934 }
935
936 return buffer.commit();
937 }
938
946 template <typename... TArgs>
947 inline size_t add_way_node_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
948
949 {
950 WayNodeListBuilder builder{buffer};
951 (void)std::initializer_list<int>{
952 (detail::nodes_handler::set_value(builder, args), 0)...
953 };
954 }
955
956 return buffer.commit();
957 }
958
966 template <typename... TArgs>
967 inline size_t add_tag_list(osmium::memory::Buffer& buffer, const TArgs&... args) {
968
969 {
970 TagListBuilder builder{buffer};
971 (void)std::initializer_list<int>{
972 (detail::tags_handler::set_value(builder, args), 0)...
973 };
974 }
975
976 return buffer.commit();
977 }
978
979 } // namespace builder
980
981} // namespace osmium
982
983#endif // OSMIUM_BUILDER_ATTR_HPP
constexpr detail::comments_from_iterator_pair< TCommentIterator > _comments(TCommentIterator first, TCommentIterator last)
Definition: attr.hpp:484
constexpr _location(const osmium::Location &value) noexcept
Definition: attr.hpp:228
std::initializer_list< std::pair< const char *, const char * > > tag_ilist
Definition: attr.hpp:395
constexpr _comment(const comment_type &value) noexcept
Definition: attr.hpp:477
constexpr detail::members_from_iterator_pair< TMemberIterator > _members(TMemberIterator first, TMemberIterator last)
Definition: attr.hpp:452
constexpr detail::inner_ring_from_iterator_pair< TIdIterator > _inner_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:530
std::pair< const std::string &, const std::string & > pair_of_strings
Definition: attr.hpp:242
size_t add_tag_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:967
constexpr _member(const member_type &value) noexcept
Definition: attr.hpp:439
size_t add_area(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:922
_tag(const pair_of_cstrings &value) noexcept
Definition: attr.hpp:358
constexpr _user(const char *val) noexcept
Definition: attr.hpp:235
std::initializer_list< osmium::NodeRef > node_ref_ilist
Definition: attr.hpp:430
std::initializer_list< osmium::object_id_type > object_id_ilist
Definition: attr.hpp:423
size_t add_node(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:835
std::pair< const char *const, const char *const > pair_of_cstrings
Definition: attr.hpp:241
size_t add_relation(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:878
size_t add_way(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:856
std::initializer_list< comment_type > comment_ilist
Definition: attr.hpp:495
_t(const char *tags)
Definition: attr.hpp:379
constexpr detail::tags_from_iterator_pair< TTagIterator > _tags(TTagIterator first, TTagIterator last)
Definition: attr.hpp:384
size_t add_way_node_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:947
constexpr detail::outer_ring_from_iterator_pair< TIdIterator > _outer_ring(TIdIterator first, TIdIterator last)
Definition: attr.hpp:504
constexpr _node(osmium::object_id_type value) noexcept
Definition: attr.hpp:405
constexpr detail::nodes_from_iterator_pair< TIdIterator > _nodes(TIdIterator first, TIdIterator last)
Definition: attr.hpp:412
size_t add_changeset(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition: attr.hpp:900
std::initializer_list< member_type > member_ilist
Definition: attr.hpp:463
#define OSMIUM_ATTRIBUTE(_handler, _name, _type)
Definition: attr.hpp:179
#define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type)
Definition: attr.hpp:183
Definition: attr.hpp:308
constexpr osmium::Timestamp date() const noexcept
Definition: attr.hpp:324
constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char *user, const char *text) noexcept
Definition: attr.hpp:317
osmium::user_id_type m_uid
Definition: attr.hpp:311
constexpr const char * text() const noexcept
Definition: attr.hpp:336
const char * m_text
Definition: attr.hpp:313
constexpr const char * user() const noexcept
Definition: attr.hpp:332
constexpr osmium::user_id_type uid() const noexcept
Definition: attr.hpp:328
const char * m_user
Definition: attr.hpp:312
osmium::Timestamp m_date
Definition: attr.hpp:310
Definition: attr.hpp:276
osmium::object_id_type m_ref
Definition: attr.hpp:279
osmium::item_type m_type
Definition: attr.hpp:278
osmium::item_type type() const noexcept
Definition: attr.hpp:294
osmium::object_id_type ref() const noexcept
Definition: attr.hpp:298
member_type_string(char type, osmium::object_id_type ref, std::string &&role) noexcept
Definition: attr.hpp:290
const char * role() const noexcept
Definition: attr.hpp:302
std::string m_role
Definition: attr.hpp:280
member_type_string(osmium::item_type type, osmium::object_id_type ref, std::string &&role)
Definition: attr.hpp:284
Definition: attr.hpp:244
member_type(char type, osmium::object_id_type ref, const char *role="") noexcept
Definition: attr.hpp:258
constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char *role="") noexcept
Definition: attr.hpp:252
osmium::object_id_type m_ref
Definition: attr.hpp:247
osmium::item_type m_type
Definition: attr.hpp:246
constexpr osmium::object_id_type ref() const noexcept
Definition: attr.hpp:266
constexpr const char * role() const noexcept
Definition: attr.hpp:270
constexpr osmium::item_type type() const noexcept
Definition: attr.hpp:262
const char * m_role
Definition: attr.hpp:248
Definition: changeset.hpp:59
An OSM Changeset, a group of changes made by a single user over a short period of time.
Definition: changeset.hpp:146
Definition: location.hpp:271
Definition: node_ref.hpp:50
Definition: node.hpp:48
Definition: object.hpp:64
Definition: relation.hpp:56
Definition: timestamp.hpp:175
Definition: builder.hpp:56
osmium::memory::Buffer & buffer() noexcept
Return the buffer this builder is using.
Definition: builder.hpp:198
Definition: attr.hpp:342
OSMIUM_ATTRIBUTE_ITER(tags_handler, tags_from_iterator_pair)
constexpr const char * get_user(const attr::_user &user, const TArgs &...) noexcept
Definition: attr.hpp:652
void add_user(TBuilder &builder, const TArgs &... args)
Definition: attr.hpp:667
std::enable_if<!is_handled_by< THandler, TArgs... >::value >::type add_list(osmium::builder::Builder &, const TArgs &...) noexcept
Definition: attr.hpp:806
void add_basic(TBuilder &builder, const TArgs &... args) noexcept
Definition: attr.hpp:643
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _id, osmium::object_id_type)
constexpr _deleted(bool value=true) noexcept
Definition: attr.hpp:205
NodeRefListBuilder< InnerRing > InnerRingBuilder
Definition: osm_object_builder.hpp:226
constexpr _visible(bool value=true) noexcept
Definition: attr.hpp:210
NodeRefListBuilder< WayNodeList > WayNodeListBuilder
Definition: osm_object_builder.hpp:224
NodeRefListBuilder< OuterRing > OuterRingBuilder
Definition: osm_object_builder.hpp:225
InputIterator< Reader > end(Reader &)
Definition: reader_iterator.hpp:47
InputIterator< Reader > begin(Reader &reader)
Definition: reader_iterator.hpp:43
type
Definition: entity_bits.hpp:63
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53
item_type char_to_item_type(const char c) noexcept
Definition: item_type.hpp:90
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
std::vector< std::string > split_string(const std::string &str, const char sep, bool compact=false)
Definition: string.hpp:50
uint32_t changeset_id_type
Type for OSM changeset IDs.
Definition: types.hpp:48
constexpr _timestamp(const osmium::Timestamp &value) noexcept
Definition: attr.hpp:215
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition: types.hpp:45
item_type
Definition: item_type.hpp:45
_timestamp(const std::string &value)
Definition: attr.hpp:223
uint32_t num_comments_type
Type for changeset num_comments.
Definition: types.hpp:52
uint32_t num_changes_type
Type for changeset num_changes.
Definition: types.hpp:51
Definition: location.hpp:555
Definition: attr.hpp:821
Definition: attr.hpp:822
Definition: attr.hpp:818
Definition: attr.hpp:820
Definition: attr.hpp:819
Definition: attr.hpp:564
static void set_value(osmium::Changeset &changeset, attr::_created_at created_at) noexcept
Definition: attr.hpp:582
static void set_value(osmium::Changeset &changeset, attr::_cid id) noexcept
Definition: attr.hpp:570
static void set_value(osmium::Changeset &changeset, attr::_num_changes num_changes) noexcept
Definition: attr.hpp:574
static void set_value(osmium::Changeset &changeset, attr::_uid uid) noexcept
Definition: attr.hpp:590
static void set_value(osmium::Changeset &changeset, attr::_num_comments num_comments) noexcept
Definition: attr.hpp:578
static void set_value(osmium::Changeset &changeset, attr::_closed_at closed_at) noexcept
Definition: attr.hpp:586
static void set_value(osmium::Changeset &, const TDummy &) noexcept
Definition: attr.hpp:567
Definition: attr.hpp:757
static void set_value(ChangesetDiscussionBuilder &builder, const attr::detail::comments_from_iterator_pair< TIterator > &comments)
Definition: attr.hpp:769
static void set_value(ChangesetDiscussionBuilder &, const TDummy &) noexcept
Definition: attr.hpp:760
static void set_value(ChangesetDiscussionBuilder &builder, const attr::_comment &comment)
Definition: attr.hpp:763
Definition: attr.hpp:738
static void set_value(RelationMemberListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:741
static void set_value(RelationMemberListBuilder &builder, const attr::detail::members_from_iterator_pair< TIterator > &members)
Definition: attr.hpp:749
static void set_value(RelationMemberListBuilder &builder, const attr::_member &member)
Definition: attr.hpp:744
Definition: attr.hpp:632
static void set_value(osmium::Node &node, attr::_location location) noexcept
Definition: attr.hpp:636
Definition: attr.hpp:719
static void set_value(WayNodeListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:722
static void set_value(WayNodeListBuilder &builder, const attr::_node &node_ref)
Definition: attr.hpp:725
static void set_value(WayNodeListBuilder &builder, const attr::detail::nodes_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:730
Definition: attr.hpp:596
static void set_value(osmium::OSMObject &object, attr::_cid changeset) noexcept
Definition: attr.hpp:622
static void set_value(osmium::OSMObject &object, attr::_deleted deleted) noexcept
Definition: attr.hpp:614
static void set_value(osmium::OSMObject &object, attr::_timestamp timestamp) noexcept
Definition: attr.hpp:618
static void set_value(osmium::OSMObject &, const TDummy &) noexcept
Definition: attr.hpp:599
static void set_value(osmium::OSMObject &object, attr::_id id) noexcept
Definition: attr.hpp:602
static void set_value(osmium::OSMObject &object, attr::_visible visible) noexcept
Definition: attr.hpp:610
static void set_value(osmium::OSMObject &object, attr::_version version) noexcept
Definition: attr.hpp:606
static void set_value(osmium::OSMObject &object, attr::_uid uid) noexcept
Definition: attr.hpp:626
Definition: attr.hpp:778
static void set_value(AreaBuilder &parent, const attr::detail::outer_ring_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:785
static void set_value(AreaBuilder &, const TDummy &) noexcept
Definition: attr.hpp:781
static void set_value(AreaBuilder &parent, const attr::detail::inner_ring_from_iterator_pair< TIterator > &nodes)
Definition: attr.hpp:793
Definition: attr.hpp:673
static void set_value(TagListBuilder &builder, const attr::_t &tags)
Definition: attr.hpp:702
static void set_value(TagListBuilder &builder, const attr::detail::tags_from_iterator_pair< TIterator > &tags)
Definition: attr.hpp:696
static void set_value(TagListBuilder &builder, const attr::_tag &tag)
Definition: attr.hpp:679
static void set_value(TagListBuilder &, const TDummy &) noexcept
Definition: attr.hpp:676