Libosmium: include/osmium/builder/attr.hpp Source File

Libosmium Fast and flexible C++ library for working with OpenStreetMap data

Loading...
Searching...
No Matches
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-2026 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
36#include <osmium/builder/builder.hpp>
37#include <osmium/builder/osm_object_builder.hpp>
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#include <osmium/util/string.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_t<_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
199 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _id, osmium::object_id_type);
200 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(object_handler, _version, osmium::object_version_type);
201 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(entity_handler, _uid, osmium::user_id_type);
202 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(entity_handler, _cid, osmium::changeset_id_type);
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
214 OSMIUM_ATTRIBUTE(object_handler, _timestamp, osmium::Timestamp)
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
227 OSMIUM_ATTRIBUTE(node_handler, _location, osmium::Location)
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
244 class member_type {
245
246 osmium::item_type m_type;
247 osmium::object_id_type m_ref;
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 :
259 member_type(osmium::char_to_item_type(type), ref, role) {
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
276 class member_type_string {
277
278 osmium::item_type m_type;
279 osmium::object_id_type m_ref;
280 std::string m_role;
281
282 public:
283
284 member_type_string(osmium::item_type type, osmium::object_id_type ref, std::string&& role) :
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 :
291 member_type_string(osmium::char_to_item_type(type), ref, std::move(role)) {
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
308 class comment_type {
309
310 osmium::Timestamp m_date;
311 osmium::user_id_type m_uid;
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
357 OSMIUM_ATTRIBUTE(tags_handler, _tag, pair_of_cstrings)
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 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 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 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
471 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_changes, osmium::num_changes_type);
472 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _num_comments, osmium::num_comments_type);
473 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _created_at, osmium::Timestamp);
474 OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(changeset_handler, _closed_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 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 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 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
634 using object_handler::set_value;
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 constexpr const char* get_user(const attr::_user& user, const TArgs&... /*args*/) noexcept {
653 return user.value;
654 }
655
656 constexpr const char* get_user() noexcept {
657 return "";
658 }
659
660 template <typename TFirst, typename... TRest>
661 constexpr std::enable_if_t<!std::is_same<attr::_user, TFirst>::value, const char*>
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
673 struct tags_handler {
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
719 struct nodes_handler {
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
738 struct members_handler {
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
757 struct discussion_handler {
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
778 struct ring_handler {
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 std::enable_if_t<!is_handled_by<THandler, TArgs...>::value>
806 add_list(osmium::builder::Builder& /*parent*/, const TArgs&... /*args*/) noexcept {
807 }
808
809 template <typename TBuilder, typename THandler, typename... TArgs>
810 inline std::enable_if_t<is_handled_by<THandler, TArgs...>::value>
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 {};
820 struct any_relation_handlers : public object_handler, public tags_handler, public members_handler {};
821 struct any_area_handlers : public object_handler, public tags_handler, public ring_handler {};
822 struct any_changeset_handlers : public changeset_handler, public tags_handler, public discussion_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
_comments
constexpr detail::comments_from_iterator_pair< TCommentIterator > _comments(TCommentIterator first, TCommentIterator last)
Definition attr.hpp:484
_location
constexpr _location(const osmium::Location &value) noexcept
Definition attr.hpp:228
_comment
constexpr _comment(const comment_type &value) noexcept
Definition attr.hpp:477
_members
constexpr detail::members_from_iterator_pair< TMemberIterator > _members(TMemberIterator first, TMemberIterator last)
Definition attr.hpp:452
_inner_ring
constexpr detail::inner_ring_from_iterator_pair< TIdIterator > _inner_ring(TIdIterator first, TIdIterator last)
Definition attr.hpp:530
pair_of_strings
std::pair< const std::string &, const std::string & > pair_of_strings
Definition attr.hpp:242
add_tag_list
size_t add_tag_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:967
_member
constexpr _member(const member_type &value) noexcept
Definition attr.hpp:439
OSMIUM_ATTRIBUTE_ITER
#define OSMIUM_ATTRIBUTE_ITER(_handler, _name)
Definition attr.hpp:189
node_ref_ilist
std::initializer_list< osmium::NodeRef > node_ref_ilist
Definition attr.hpp:430
add_area
size_t add_area(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:922
_tag
_tag(const pair_of_cstrings &value) noexcept
Definition attr.hpp:358
_user
constexpr _user(const char *val) noexcept
Definition attr.hpp:235
add_node
size_t add_node(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:835
pair_of_cstrings
std::pair< const char *const, const char *const > pair_of_cstrings
Definition attr.hpp:241
add_relation
size_t add_relation(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:878
add_way
size_t add_way(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:856
comment_ilist
std::initializer_list< comment_type > comment_ilist
Definition attr.hpp:495
_t
_t(const char *tags)
Definition attr.hpp:379
_tags
constexpr detail::tags_from_iterator_pair< TTagIterator > _tags(TTagIterator first, TTagIterator last)
Definition attr.hpp:384
add_way_node_list
size_t add_way_node_list(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:947
_outer_ring
constexpr detail::outer_ring_from_iterator_pair< TIdIterator > _outer_ring(TIdIterator first, TIdIterator last)
Definition attr.hpp:504
_node
constexpr _node(osmium::object_id_type value) noexcept
Definition attr.hpp:405
_nodes
constexpr detail::nodes_from_iterator_pair< TIdIterator > _nodes(TIdIterator first, TIdIterator last)
Definition attr.hpp:412
add_changeset
size_t add_changeset(osmium::memory::Buffer &buffer, const TArgs &... args)
Definition attr.hpp:900
tag_ilist
std::initializer_list< std::pair< const char *, const char * > > tag_ilist
Definition attr.hpp:395
member_ilist
std::initializer_list< member_type > member_ilist
Definition attr.hpp:463
OSMIUM_ATTRIBUTE
#define OSMIUM_ATTRIBUTE(_handler, _name, _type)
Definition attr.hpp:179
object_id_ilist
std::initializer_list< osmium::object_id_type > object_id_ilist
Definition attr.hpp:423
OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR
#define OSMIUM_ATTRIBUTE_WITH_CONSTRUCTOR(_handler, _name, _type)
Definition attr.hpp:183
buffer.hpp
builder.hpp
changeset.hpp
comment_type
Definition attr.hpp:308
comment_type::date
constexpr osmium::Timestamp date() const noexcept
Definition attr.hpp:324
comment_type::comment_type
constexpr comment_type(osmium::Timestamp date, osmium::user_id_type uid, const char *user, const char *text) noexcept
Definition attr.hpp:317
comment_type::m_uid
osmium::user_id_type m_uid
Definition attr.hpp:311
comment_type::text
constexpr const char * text() const noexcept
Definition attr.hpp:336
comment_type::m_text
const char * m_text
Definition attr.hpp:313
comment_type::user
constexpr const char * user() const noexcept
Definition attr.hpp:332
comment_type::uid
constexpr osmium::user_id_type uid() const noexcept
Definition attr.hpp:328
comment_type::m_user
const char * m_user
Definition attr.hpp:312
comment_type::m_date
osmium::Timestamp m_date
Definition attr.hpp:310
member_type_string::m_ref
osmium::object_id_type m_ref
Definition attr.hpp:279
member_type_string::m_type
osmium::item_type m_type
Definition attr.hpp:278
member_type_string::type
osmium::item_type type() const noexcept
Definition attr.hpp:294
member_type_string::ref
osmium::object_id_type ref() const noexcept
Definition attr.hpp:298
member_type_string::member_type_string
member_type_string(char type, osmium::object_id_type ref, std::string &&role) noexcept
Definition attr.hpp:290
member_type_string::role
const char * role() const noexcept
Definition attr.hpp:302
member_type_string::m_role
std::string m_role
Definition attr.hpp:280
member_type_string::member_type_string
member_type_string(osmium::item_type type, osmium::object_id_type ref, std::string &&role)
Definition attr.hpp:284
member_type
Definition attr.hpp:244
member_type::member_type
member_type(char type, osmium::object_id_type ref, const char *role="") noexcept
Definition attr.hpp:258
member_type::member_type
constexpr member_type(osmium::item_type type, osmium::object_id_type ref, const char *role="") noexcept
Definition attr.hpp:252
member_type::m_ref
osmium::object_id_type m_ref
Definition attr.hpp:247
member_type::m_type
osmium::item_type m_type
Definition attr.hpp:246
member_type::ref
constexpr osmium::object_id_type ref() const noexcept
Definition attr.hpp:266
member_type::role
constexpr const char * role() const noexcept
Definition attr.hpp:270
member_type::type
constexpr osmium::item_type type() const noexcept
Definition attr.hpp:262
member_type::m_role
const char * m_role
Definition attr.hpp:248
osmium::ChangesetComment
Definition changeset.hpp:59
osmium::Changeset
An OSM Changeset, a group of changes made by a single user over a short period of time.
Definition changeset.hpp:146
osmium::Location
Definition location.hpp:279
osmium::NodeRef
Definition node_ref.hpp:50
osmium::Node
Definition node.hpp:48
osmium::OSMObject
Definition object.hpp:64
osmium::RelationMember
Definition relation.hpp:56
osmium::Timestamp
Definition timestamp.hpp:175
osmium::builder::Builder
Definition builder.hpp:56
osmium::builder::Builder::buffer
osmium::memory::Buffer & buffer() noexcept
Return the buffer this builder is using.
Definition builder.hpp:198
item_type.hpp
location.hpp
detail
Definition attr.hpp:342
detail::add_list
std::enable_if_t<!is_handled_by< THandler, TArgs... >::value > add_list(osmium::builder::Builder &, const TArgs &...) noexcept
Definition attr.hpp:806
detail::get_user
constexpr const char * get_user() noexcept
Definition attr.hpp:656
detail::add_user
void add_user(TBuilder &builder, const TArgs &... args)
Definition attr.hpp:667
detail::add_basic
void add_basic(TBuilder &builder, const TArgs &... args) noexcept
Definition attr.hpp:643
osmium::builder::attr
Definition attr.hpp:197
osmium::builder::attr::_deleted
constexpr _deleted(bool value=true) noexcept
Definition attr.hpp:205
osmium::builder
Classes for building OSM objects and other items in buffers.
Definition attr.hpp:62
osmium::builder::_visible
constexpr _visible(bool value=true) noexcept
Definition attr.hpp:210
osmium
Namespace for everything in the Osmium library.
Definition assembler.hpp:53
osmium::char_to_item_type
item_type char_to_item_type(const char c) noexcept
Definition item_type.hpp:90
osmium::changeset_id_type
uint32_t changeset_id_type
Type for OSM changeset IDs.
Definition types.hpp:48
osmium::split_string
std::vector< std::string > split_string(const std::string &str, const char sep, bool compact=false)
Definition string.hpp:50
osmium::_timestamp
constexpr _timestamp(const osmium::Timestamp &value) noexcept
Definition attr.hpp:215
osmium::num_changes_type
uint32_t num_changes_type
Type for changeset num_changes.
Definition types.hpp:51
osmium::item_type
item_type
Definition item_type.hpp:45
osmium::num_comments_type
uint32_t num_comments_type
Type for changeset num_comments.
Definition types.hpp:52
osmium::object_id_type
int64_t object_id_type
Type for OSM object (node, way, or relation) IDs.
Definition types.hpp:45
osmium::object_version_type
uint32_t object_version_type
Type for OSM object version number.
Definition types.hpp:47
osmium::user_id_type
uint32_t user_id_type
Type for OSM user IDs.
Definition types.hpp:49
std
Definition location.hpp:654
node.hpp
node_ref.hpp
object.hpp
osm_object_builder.hpp
relation.hpp
string.hpp
detail::any_area_handlers
Definition attr.hpp:821
detail::any_changeset_handlers
Definition attr.hpp:822
detail::any_node_handlers
Definition attr.hpp:818
detail::any_relation_handlers
Definition attr.hpp:820
detail::any_way_handlers
Definition attr.hpp:819
detail::changeset_handler
Definition attr.hpp:564
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_created_at created_at) noexcept
Definition attr.hpp:582
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_cid id) noexcept
Definition attr.hpp:570
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_num_changes num_changes) noexcept
Definition attr.hpp:574
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_uid uid) noexcept
Definition attr.hpp:590
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_num_comments num_comments) noexcept
Definition attr.hpp:578
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &changeset, attr::_closed_at closed_at) noexcept
Definition attr.hpp:586
detail::changeset_handler::set_value
static void set_value(osmium::Changeset &, const TDummy &) noexcept
Definition attr.hpp:567
detail::discussion_handler
Definition attr.hpp:757
detail::discussion_handler::set_value
static void set_value(ChangesetDiscussionBuilder &builder, const attr::detail::comments_from_iterator_pair< TIterator > &comments)
Definition attr.hpp:769
detail::discussion_handler::set_value
static void set_value(ChangesetDiscussionBuilder &, const TDummy &) noexcept
Definition attr.hpp:760
detail::discussion_handler::set_value
static void set_value(ChangesetDiscussionBuilder &builder, const attr::_comment &comment)
Definition attr.hpp:763
detail::members_handler
Definition attr.hpp:738
detail::members_handler::set_value
static void set_value(RelationMemberListBuilder &, const TDummy &) noexcept
Definition attr.hpp:741
detail::members_handler::set_value
static void set_value(RelationMemberListBuilder &builder, const attr::detail::members_from_iterator_pair< TIterator > &members)
Definition attr.hpp:749
detail::members_handler::set_value
static void set_value(RelationMemberListBuilder &builder, const attr::_member &member)
Definition attr.hpp:744
detail::node_handler
Definition attr.hpp:632
detail::node_handler::set_value
static void set_value(osmium::Node &node, attr::_location location) noexcept
Definition attr.hpp:636
detail::nodes_handler
Definition attr.hpp:719
detail::nodes_handler::set_value
static void set_value(WayNodeListBuilder &, const TDummy &) noexcept
Definition attr.hpp:722
detail::nodes_handler::set_value
static void set_value(WayNodeListBuilder &builder, const attr::_node &node_ref)
Definition attr.hpp:725
detail::nodes_handler::set_value
static void set_value(WayNodeListBuilder &builder, const attr::detail::nodes_from_iterator_pair< TIterator > &nodes)
Definition attr.hpp:730
detail::object_handler
Definition attr.hpp:596
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_cid changeset) noexcept
Definition attr.hpp:622
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_deleted deleted) noexcept
Definition attr.hpp:614
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_timestamp timestamp) noexcept
Definition attr.hpp:618
detail::object_handler::set_value
static void set_value(osmium::OSMObject &, const TDummy &) noexcept
Definition attr.hpp:599
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_id id) noexcept
Definition attr.hpp:602
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_visible visible) noexcept
Definition attr.hpp:610
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_version version) noexcept
Definition attr.hpp:606
detail::object_handler::set_value
static void set_value(osmium::OSMObject &object, attr::_uid uid) noexcept
Definition attr.hpp:626
detail::ring_handler
Definition attr.hpp:778
detail::ring_handler::set_value
static void set_value(AreaBuilder &parent, const attr::detail::outer_ring_from_iterator_pair< TIterator > &nodes)
Definition attr.hpp:785
detail::ring_handler::set_value
static void set_value(AreaBuilder &, const TDummy &) noexcept
Definition attr.hpp:781
detail::ring_handler::set_value
static void set_value(AreaBuilder &parent, const attr::detail::inner_ring_from_iterator_pair< TIterator > &nodes)
Definition attr.hpp:793
detail::tags_handler
Definition attr.hpp:673
detail::tags_handler::set_value
static void set_value(TagListBuilder &builder, const attr::_t &tags)
Definition attr.hpp:702
detail::tags_handler::set_value
static void set_value(TagListBuilder &builder, const attr::detail::tags_from_iterator_pair< TIterator > &tags)
Definition attr.hpp:696
detail::tags_handler::set_value
static void set_value(TagListBuilder &builder, const attr::_tag &tag)
Definition attr.hpp:679
detail::tags_handler::set_value
static void set_value(TagListBuilder &, const TDummy &) noexcept
Definition attr.hpp:676
timestamp.hpp
types.hpp