Antkeeper  0.0.1
brep-attribute-map.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP
21 #define ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP
22 
25 #include <iterator>
26 #include <memory>
27 #include <stdexcept>
28 #include <type_traits>
29 #include <unordered_map>
30 #include <utility>
31 
32 namespace geom {
33 
38 {
39 public:
40  template <class Iter, bool Const>
42  {
43  public:
44  using iterator_type = Iter;
45  using iterator_category = std::bidirectional_iterator_tag;
46  using iterator_concept = std::bidirectional_iterator_tag;
47  using difference_type = std::iter_difference_t<Iter>;
49  using pointer = std::conditional<Const, const value_type*, value_type*>::type;
50  using reference = std::conditional<Const, const value_type&, value_type&>::type;
51 
52  [[nodiscard]] inline constexpr reference operator*() const noexcept
53  {
54  return *m_it->second;
55  }
56 
57  [[nodiscard]] inline constexpr pointer operator->() const noexcept
58  {
59  return &(*m_it->second);
60  }
61 
62  [[nodiscard]] inline constexpr reference operator[](difference_type i) const noexcept
63  {
64  return *(m_it[i]);
65  }
66 
67  inline iterator_template& operator++() noexcept
68  {
69  ++m_it;
70  return *this;
71  }
72 
73  [[nodiscard]] inline iterator_template operator++(int) noexcept
74  {
75  iterator_template tmp = *this;
76  ++(*this);
77  return tmp;
78  }
79 
80  inline iterator_template& operator--() noexcept
81  {
82  --m_it;
83  return *this;
84  }
85 
86  [[nodiscard]] inline iterator_template operator--(int) noexcept
87  {
88  iterator_template tmp = *this;
89  --(*this);
90  return tmp;
91  }
92 
94  {
95  m_it += n;
96  return *this;
97  }
98 
100  {
101  m_it -= n;
102  return *this;
103  }
104 
105  [[nodiscard]] inline bool operator==(const iterator_template& other) const noexcept
106  {
107  return m_it == other.m_it;
108  };
109 
110  [[nodiscard]] inline std::weak_ordering operator<=>(const iterator_template& other) const noexcept
111  {
112  return m_it <=> other.m_it;
113  }
114 
115  [[nodiscard]] inline difference_type operator-(const iterator_template& rhs) const noexcept
116  {
117  return m_it - rhs.m_it;
118  }
119 
120  [[nodiscard]] inline iterator_template operator+(difference_type n) const noexcept
121  {
122  return iterator_template{m_it + n};
123  }
124 
125  [[nodiscard]] inline iterator_template operator-(difference_type n) const noexcept
126  {
127  return iterator_template{m_it - n};
128  }
129 
130  [[nodiscard]] friend iterator_template operator+(difference_type lhs, const iterator_template& rhs) noexcept
131  {
132  return iterator_template{lhs + rhs.m_it};
133  }
134 
135  [[nodiscard]] friend iterator_template operator-(difference_type lhs, const iterator_template& rhs) noexcept
136  {
137  return iterator_template{lhs - rhs.m_it};
138  }
139 
140  private:
141  friend class brep_attribute_map;
142 
143  iterator_type m_it;
144  };
145 
148 
151 
154  [[nodiscard]] inline const_iterator begin() const noexcept
155  {
156  const_iterator it;
157  it.m_it = m_attributes.begin();
158  return it;
159  }
160  [[nodiscard]] inline iterator begin() noexcept
161  {
162  iterator it;
163  it.m_it = m_attributes.begin();
164  return it;
165  }
166  [[nodiscard]] inline const_iterator cbegin() const noexcept
167  {
168  return begin();
169  }
171 
174  [[nodiscard]] inline const_iterator end() const noexcept
175  {
176  const_iterator it;
177  it.m_it = m_attributes.end();
178  return it;
179  }
180  [[nodiscard]] inline iterator end() noexcept
181  {
182  iterator it;
183  it.m_it = m_attributes.end();
184  return it;
185  }
186  [[nodiscard]] inline const_iterator cend() const noexcept
187  {
188  return end();
189  }
191 
195 
197  [[nodiscard]] inline bool empty() const noexcept
198  {
199  return m_attributes.empty();
200  }
201 
203  [[nodiscard]] inline std::size_t size() const noexcept
204  {
205  return m_attributes.size();
206  }
207 
211 
215  inline void clear() noexcept
216  {
217  m_attributes.clear();
218  }
219 
229  template <class T>
231  {
232  if (auto i = m_attributes.find(name); i != m_attributes.end())
233  {
234  i->second.reset();
235  i->second = std::make_unique<brep_attribute<T>>(name, m_element_count);
236 
237  iterator it;
238  it.m_it = i;
239  return it;
240  }
241 
242  iterator it;
243  it.m_it = m_attributes.emplace(name, std::make_unique<brep_attribute<T>>(name, m_element_count)).first;
244  return it;
245  }
246 
254  inline iterator erase(iterator pos)
255  {
256  iterator it;
257  it.m_it = m_attributes.erase(pos.m_it);
258  return it;
259  }
260 
268  inline std::size_t erase(hash::fnv1a32_t name)
269  {
270  return m_attributes.erase(name);
271  }
272 
282  template <class T>
283  std::pair<iterator, bool> try_emplace(hash::fnv1a32_t name)
284  {
285  if (auto i = m_attributes.find(name); i != m_attributes.end())
286  {
287  iterator it;
288  it.m_it = i;
289  return {it, false};
290  }
291 
292  auto pair = m_attributes.emplace(name, std::make_unique<brep_attribute<T>>(name, m_element_count));
293  iterator it;
294  it.m_it = pair.first;
295  return {it, pair.second};
296  }
297 
301 
312  template <class T>
313  [[nodiscard]] const brep_attribute<T>& at(hash::fnv1a32_t name) const
314  {
315  auto it = find(name);
316  if (it == end())
317  {
318  throw std::out_of_range("B-rep attribute not found");
319  }
320 
321  return static_cast<const brep_attribute<T>&>(*it);
322  }
323  template <class T>
324  [[nodiscard]] brep_attribute<T>& at(hash::fnv1a32_t name)
325  {
326  auto it = find(name);
327  if (it == end())
328  {
329  throw std::out_of_range("B-rep attribute not found");
330  }
331 
332  return static_cast<brep_attribute<T>&>(*it);
333  }
335 
344  [[nodiscard]] inline const_iterator find(hash::fnv1a32_t name) const
345  {
346  const_iterator it;
347  it.m_it = m_attributes.find(name);
348  return it;
349  }
350  [[nodiscard]] inline iterator find(hash::fnv1a32_t name)
351  {
352  iterator it;
353  it.m_it = m_attributes.find(name);
354  return it;
355  }
357 
365  [[nodiscard]] inline bool contains(hash::fnv1a32_t name) const
366  {
367  return m_attributes.contains(name);
368  }
369 
371 
372 private:
373  template <class T>
375  friend class brep_mesh;
376 
377  brep_attribute_map& operator=(const brep_attribute_map& other)
378  {
379  m_element_count = other.m_element_count;
380  m_attributes.clear();
381  for (const auto& [key, value]: other.m_attributes)
382  {
383  m_attributes.emplace(key, value->clone());
384  }
385 
386  return *this;
387  }
388 
389  std::size_t m_element_count{};
390  std::unordered_map<hash::fnv1a32_t, std::unique_ptr<brep_attribute_base>> m_attributes;
391 };
392 
393 } // namespace geom
394 
395 #endif // ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP
Abstract base class for B-rep element attributes.
std::iter_difference_t< Iter > difference_type
iterator_template operator++(int) noexcept
iterator_template operator--(int) noexcept
constexpr pointer operator->() const noexcept
std::bidirectional_iterator_tag iterator_concept
std::conditional< Const, const value_type &, value_type & >::type reference
std::conditional< Const, const value_type *, value_type * >::type pointer
iterator_template operator+(difference_type n) const noexcept
iterator_template operator-(difference_type n) const noexcept
difference_type operator-(const iterator_template &rhs) const noexcept
std::bidirectional_iterator_tag iterator_category
iterator_template & operator+=(difference_type n) noexcept
constexpr reference operator[](difference_type i) const noexcept
iterator_template & operator-=(difference_type n) noexcept
std::weak_ordering operator<=>(const iterator_template &other) const noexcept
friend iterator_template operator-(difference_type lhs, const iterator_template &rhs) noexcept
friend iterator_template operator+(difference_type lhs, const iterator_template &rhs) noexcept
bool operator==(const iterator_template &other) const noexcept
constexpr reference operator*() const noexcept
Maps names to B-rep attributes.
const_iterator cbegin() const noexcept
Returns an iterator to the first attribute.
bool empty() const noexcept
Returns true if the container is empty, false otherwise.
iterator find(hash::fnv1a32_t name)
Finds an attribute with the given name.
const_iterator find(hash::fnv1a32_t name) const
Finds an attribute with the given name.
std::size_t size() const noexcept
Returns the number of attributes in the container.
iterator erase(iterator pos)
Removes an attribute from the container.
std::pair< iterator, bool > try_emplace(hash::fnv1a32_t name)
Constructs a new attribute if an attribute with the given name does not exist.
const_iterator begin() const noexcept
Returns an iterator to the first attribute.
std::size_t erase(hash::fnv1a32_t name)
Removes an attribute from the container.
iterator end() noexcept
Returns an iterator to the attribute following the last attribute.
const brep_attribute< T > & at(hash::fnv1a32_t name) const
Returns a reference to the attribute with the given name.
iterator emplace(hash::fnv1a32_t name)
Constructs a new attribute.
const_iterator end() const noexcept
Returns an iterator to the attribute following the last attribute.
void clear() noexcept
Removes all attributes from the container.
brep_attribute< T > & at(hash::fnv1a32_t name)
Returns a reference to the attribute with the given name.
iterator begin() noexcept
Returns an iterator to the first attribute.
iterator_template< std::unordered_map< hash::fnv1a32_t, std::unique_ptr< brep_attribute_base > >::const_iterator, true > const_iterator
bool contains(hash::fnv1a32_t name) const
Checks if there is an attribute with a given name in the container.
iterator_template< std::unordered_map< hash::fnv1a32_t, std::unique_ptr< brep_attribute_base > >::iterator, false > iterator
const_iterator cend() const noexcept
Returns an iterator to the attribute following the last attribute.
Per-element B-rep data.
Container for B-rep elements.
Boundary representation (B-rep) of a mesh.
Definition: brep-mesh.hpp:34
Geometric algorithms.
32-bit FNV-1a hash value.
Definition: fnv1a.hpp:117