1 #ifndef OSMIUM_OSM_RELATION_HPP 2 #define OSMIUM_OSM_RELATION_HPP 3 4 /* 5 6 This file is part of Osmium (https://osmcode.org/libosmium). 7 8 Copyright 2013-2021 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 <osmium/memory/collection.hpp> // IWYU pragma: keep 37 #include <osmium/memory/item.hpp> 38 #include <osmium/osm/entity.hpp> 39 #include <osmium/osm/item_type.hpp> 40 #include <osmium/osm/object.hpp> 41 #include <osmium/osm/types.hpp> 42 #include <osmium/util/compatibility.hpp> 43 44 #include <cstdint> 45 #include <cstdlib> 46 #include <iterator> 47 48 namespace osmium { 49 50 namespace builder { 51 template <typename TDerived, typename T> 52 class OSMObjectBuilder; 53 54 class RelationMemberListBuilder; 55 } // namespace builder 56 57 class RelationMember : public osmium::memory::detail::ItemHelper { 58 59 friend class osmium::builder::RelationMemberListBuilder; 60 61 object_id_type m_ref; 62 item_type m_type; 63 uint16_t m_flags; 64 string_size_type m_role_size = 0; 65 endpos()66 unsigned char* endpos() { 67 return data() + osmium::memory::padded_length(sizeof(RelationMember) + m_role_size); 68 } 69 endpos() const70 const unsigned char* endpos() const { 71 return data() + osmium::memory::padded_length(sizeof(RelationMember) + m_role_size); 72 } 73 74 template <typename TMember> 75 friend class osmium::memory::CollectionIterator; 76 next()77 unsigned char* next() { 78 if (full_member()) { 79 return endpos() + reinterpret_cast<osmium::memory::Item*>(endpos())->byte_size(); 80 } 81 return endpos(); 82 } 83 next() const84 const unsigned char* next() const { 85 if (full_member()) { 86 return endpos() + reinterpret_cast<const osmium::memory::Item*>(endpos())->byte_size(); 87 } 88 return endpos(); 89 } 90 set_role_size(string_size_type size)91 void set_role_size(string_size_type size) noexcept { 92 m_role_size = size; 93 } 94 95 public: 96 97 static constexpr item_type collection_type = item_type::relation_member_list; 98 RelationMember(const object_id_type ref=0,const item_type type=item_type (),const bool full=false)99 explicit RelationMember(const object_id_type ref = 0, const item_type type = item_type(), const bool full = false) noexcept : 100 m_ref(ref), 101 m_type(type), 102 m_flags(full ? 1 : 0) { 103 } 104 105 RelationMember(const RelationMember&) = delete; 106 RelationMember& operator=(const RelationMember&) = delete; 107 108 RelationMember(RelationMember&&) = delete; 109 RelationMember& operator=(RelationMember&&) = delete; 110 111 ~RelationMember() noexcept = default; 112 ref() const113 object_id_type ref() const noexcept { 114 return m_ref; 115 } 116 117 /// @deprecated Use set_ref() instead. ref(object_id_type ref)118 OSMIUM_DEPRECATED RelationMember& ref(object_id_type ref) noexcept { 119 m_ref = ref; 120 return *this; 121 } 122 positive_ref() const123 unsigned_object_id_type positive_ref() const noexcept { 124 return static_cast<unsigned_object_id_type>(std::abs(m_ref)); 125 } 126 set_ref(const osmium::object_id_type ref)127 RelationMember& set_ref(const osmium::object_id_type ref) noexcept { 128 m_ref = ref; 129 return *this; 130 } 131 type() const132 item_type type() const noexcept { 133 return m_type; 134 } 135 full_member() const136 bool full_member() const noexcept { 137 return m_flags == 1; 138 } 139 role() const140 const char* role() const noexcept { 141 return reinterpret_cast<const char*>(data() + sizeof(RelationMember)); 142 } 143 get_object()144 OSMObject& get_object() { 145 return *reinterpret_cast<OSMObject*>(endpos()); 146 } 147 get_object() const148 const OSMObject& get_object() const { 149 return *reinterpret_cast<const OSMObject*>(endpos()); 150 } 151 152 }; // class RelationMember 153 154 class RelationMemberList : public osmium::memory::Collection<RelationMember, osmium::item_type::relation_member_list> { 155 156 public: 157 is_compatible_to(osmium::item_type t)158 constexpr static bool is_compatible_to(osmium::item_type t) noexcept { 159 return t == osmium::item_type::relation_member_list || 160 t == osmium::item_type::relation_member_list_with_full_members; 161 } 162 163 RelationMemberList() noexcept = default; 164 165 }; // class RelationMemberList 166 167 static_assert(sizeof(RelationMemberList) % osmium::memory::align_bytes == 0, "Class osmium::RelationMemberList has wrong size to be aligned properly!"); 168 169 class Relation : public OSMObject { 170 171 template <typename TDerived, typename T> 172 friend class osmium::builder::OSMObjectBuilder; 173 Relation()174 Relation() noexcept : 175 OSMObject(sizeof(Relation), osmium::item_type::relation) { 176 } 177 178 public: 179 180 static constexpr osmium::item_type itemtype = osmium::item_type::relation; 181 is_compatible_to(osmium::item_type t)182 constexpr static bool is_compatible_to(osmium::item_type t) noexcept { 183 return t == itemtype; 184 } 185 186 /// Get a reference to the member list. members()187 RelationMemberList& members() { 188 return osmium::detail::subitem_of_type<RelationMemberList>(begin(), end()); 189 } 190 191 /// Get a const reference to the member list. members() const192 const RelationMemberList& members() const { 193 return osmium::detail::subitem_of_type<const RelationMemberList>(cbegin(), cend()); 194 } 195 196 /// Get a const reference to the member list. cmembers() const197 const RelationMemberList& cmembers() const { 198 return osmium::detail::subitem_of_type<const RelationMemberList>(cbegin(), cend()); 199 } 200 201 }; // class Relation 202 203 static_assert(sizeof(Relation) % osmium::memory::align_bytes == 0, "Class osmium::Relation has wrong size to be aligned properly!"); 204 205 } // namespace osmium 206 207 #endif // OSMIUM_OSM_RELATION_HPP 208