💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
6.4 KiB

  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. #ifndef ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP
  20. #define ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP
  21. #include <engine/utility/hash/fnv1a.hpp>
  22. #include <memory>
  23. #include <vector>
  24. namespace geom {
  25. /**
  26. * Abstract base class for B-rep element attributes.
  27. */
  28. class brep_attribute_base
  29. {
  30. public:
  31. /// Returns the name of the attribute.
  32. [[nodiscard]] inline constexpr hash::fnv1a32_t name() const noexcept
  33. {
  34. return m_name;
  35. }
  36. protected:
  37. inline explicit constexpr brep_attribute_base(hash::fnv1a32_t name) noexcept:
  38. m_name(name)
  39. {}
  40. private:
  41. friend class brep_attribute_map;
  42. template <class T>
  43. friend class brep_element_container;
  44. /**
  45. * Erases the attribute value of an element with the given index.
  46. *
  47. * @param i Index of an element.
  48. */
  49. virtual void erase(std::size_t i) = 0;
  50. /**
  51. * Appends a new attribute value to the end of the container.
  52. */
  53. virtual void emplace_back() = 0;
  54. /// Returns a copy of this attribute.
  55. [[nodiscard]] virtual std::unique_ptr<brep_attribute_base> clone() const = 0;
  56. hash::fnv1a32_t m_name;
  57. };
  58. /**
  59. * Per-element B-rep data.
  60. *
  61. * @tparam T Data type.
  62. */
  63. template <class T>
  64. class brep_attribute: public brep_attribute_base
  65. {
  66. public:
  67. using value_type = T;
  68. using reference = value_type&;
  69. using const_reference = const value_type&;
  70. using pointer = value_type*;
  71. using const_pointer = const value_type*;
  72. using iterator = std::vector<value_type>::iterator;
  73. using const_iterator = std::vector<value_type>::const_iterator;
  74. using reverse_iterator = std::vector<value_type>::reverse_iterator;
  75. using const_reverse_iterator = std::vector<value_type>::const_reverse_iterator;
  76. /**
  77. * Constructs an attribute.
  78. *
  79. * @param name Name of the attribute.
  80. * @param element_count Number of elements.
  81. */
  82. brep_attribute(hash::fnv1a32_t name, std::size_t element_count):
  83. brep_attribute_base(name),
  84. m_values(element_count)
  85. {}
  86. /// @name Attribute access
  87. /// @{
  88. /**
  89. * Returns a reference to the attribute value of an element.
  90. *
  91. * @param i Index of an element.
  92. *
  93. * @return Reference to the attribute value of the element at index @p i.
  94. */
  95. /// @{
  96. [[nodiscard]] inline constexpr const_reference operator[](std::size_t i) const
  97. {
  98. return m_values[i];
  99. }
  100. [[nodiscard]] inline constexpr reference operator[](std::size_t i)
  101. {
  102. return m_values[i];
  103. }
  104. /// @}
  105. /// Returns a reference to the attribute value of the first element.
  106. /// @{
  107. [[nodiscard]] inline constexpr const_reference front() const
  108. {
  109. return m_values.front();
  110. }
  111. [[nodiscard]] inline constexpr reference front()
  112. {
  113. return m_values.front();
  114. }
  115. /// @}
  116. /// Returns a reference to the attribute value of the last element.
  117. /// @{
  118. [[nodiscard]] inline constexpr const_reference back() const
  119. {
  120. return m_values.back();
  121. }
  122. [[nodiscard]] inline constexpr reference back()
  123. {
  124. return m_values.back();
  125. }
  126. /// @}
  127. /// Returns a pointer to the underlying array serving as attribute value storage.
  128. /// @{
  129. [[nodiscard]] inline constexpr const value_type* data() const noexcept
  130. {
  131. return m_values.data();
  132. }
  133. [[nodiscard]] inline constexpr value_type* data() noexcept
  134. {
  135. return m_values.data();
  136. }
  137. /// @}
  138. /// @}
  139. /// @name Iterators
  140. /// @{
  141. /// Returns an iterator to the attribute value of the first element.
  142. /// @{
  143. [[nodiscard]] inline constexpr const_iterator begin() const noexcept
  144. {
  145. return m_values.begin();
  146. }
  147. [[nodiscard]] inline constexpr iterator begin() noexcept
  148. {
  149. return m_values.begin();
  150. }
  151. [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept
  152. {
  153. return m_values.begin();
  154. }
  155. /// @}
  156. /// Returns an iterator to the attribute value of the element following the last element.
  157. /// @{
  158. [[nodiscard]] inline constexpr const_iterator end() const noexcept
  159. {
  160. return m_values.end();
  161. }
  162. [[nodiscard]] inline constexpr iterator end() noexcept
  163. {
  164. return m_values.end();
  165. }
  166. [[nodiscard]] inline constexpr const_iterator cend() const noexcept
  167. {
  168. return m_values.end();
  169. }
  170. /// @}
  171. /// Returns a reverse iterator to the attribute value of the first element of the reversed container.
  172. /// @{
  173. [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept
  174. {
  175. return m_values.rbegin();
  176. }
  177. [[nodiscard]] inline constexpr reverse_iterator rbegin() noexcept
  178. {
  179. return m_values.rbegin();
  180. }
  181. [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept
  182. {
  183. return m_values.rbegin();
  184. }
  185. /// @}
  186. /// Returns a reverse iterator to the attribute value of the element following the last element of the reversed container.
  187. /// @{
  188. [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept
  189. {
  190. return m_values.rend();
  191. }
  192. [[nodiscard]] inline constexpr reverse_iterator rend() noexcept
  193. {
  194. return m_values.rend();
  195. }
  196. [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept
  197. {
  198. return m_values.rend();
  199. }
  200. /// @}
  201. /// @}
  202. /// @name Capacity
  203. /// @{
  204. /// Returns `true` if the container is empty, `false` otherwise.
  205. [[nodiscard]] inline constexpr bool empty() const noexcept
  206. {
  207. return m_values.empty();
  208. }
  209. /// Returns the number of attribute values in the container.
  210. [[nodiscard]] inline constexpr std::size_t size() const noexcept
  211. {
  212. return m_values.size();
  213. }
  214. /// @}
  215. private:
  216. void erase(std::size_t i) override
  217. {
  218. m_values[i] = std::move(m_values.back());
  219. m_values.pop_back();
  220. }
  221. void emplace_back() override
  222. {
  223. m_values.emplace_back();
  224. }
  225. [[nodiscard]] std::unique_ptr<brep_attribute_base> clone() const override
  226. {
  227. auto copy = std::make_unique<brep_attribute<T>>(name(), 0);
  228. copy->m_values = m_values;
  229. return std::move(copy);
  230. }
  231. std::vector<value_type> m_values;
  232. };
  233. } // namespace geom
  234. #endif // ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP