Wildmeshing Toolkit
MeshAttributeHandle.hpp
Go to the documentation of this file.
1 #pragma once
2 #if defined(MTAO_DEBUG_MESH_COMP)
3 #include <spdlog/spdlog.h>
4 #endif
5 //
7 //
9 
10 #include <variant>
11 
12 namespace wmtk {
13 class Mesh;
14 } // namespace wmtk
15 
16 namespace wmtk::attribute {
17 
18 /* @brief Handle that can construct an accessor on its own
19  * NOTE: This naming is inconsistent with the existing
20  * AttributeHandle/MeshAttributeHandle nomenclature, but in the future most
21  * applications should store MeshAttributeHandles instead of
22  * MeshAttributeHandle, and after most of those changes are made we will
23  * deprecate that name.
24  */
26 {
27 public:
28  // The variant type for storing all of the tuple types.
29  // each type within the Handle variant must have a ::Type value that indicates a type-based
30  // descriptor of the data held by the type
31 
32  using HandleVariant = std::variant<
37 
38  // Convenience class for identifying attribute types
39  using ValueVariant = std::
40  variant<char, int64_t, double, wmtk::Rational, std::tuple<char, wmtk::Rational, double>>;
41 
42  enum class HeldType { Char = 0, Int64 = 1, Double = 2, Rational = 3 };
43 
44  template <HeldType Type>
45  using held_handle_type = std::variant_alternative_t<size_t(Type), HandleVariant>;
46 
47  template <HeldType Type>
49 
50 
51  // for primitive type attributes returns the held type for primitive types
52  // takes as input basic type (char/int64/double/rational)
53  // Note this doesn't work with the hybrid type, so this only makes esnse to use in basic
54  // attribute storage
55  template <typename T>
56  constexpr static HeldType held_type_from_primitive();
57 
58  template <typename T>
59  constexpr static HeldType held_type_from_handle();
60 
61 
62  template <typename T>
63  constexpr static bool handle_type_is_basic();
64 
65 
66  friend class wmtk::Mesh;
67  friend class wmtk::hash<MeshAttributeHandle>;
68  MeshAttributeHandle() = default;
74 
75  bool operator==(const MeshAttributeHandle& o) const
76  {
77 #if defined(MTAO_DEBUG_MESH_COMP)
78  std::visit(
79  [&](const auto& h, const auto& oh) {
80  spdlog::warn(
81  "{} {} == {} {}",
82  std::string(h),
83  fmt::ptr(m_mesh),
84  std::string(oh),
85  fmt::ptr(m_mesh));
86  },
87  m_handle,
88  o.m_handle);
89 #endif
90  return m_handle == o.m_handle && m_mesh == o.m_mesh;
91  }
92 
93 
94  // reutrns if the target mesh is the same as the one represented in the handle
95  bool is_same_mesh(const Mesh&) const;
96 
97 
98  // returns if this handle was initialized
99  bool is_valid() const;
100 
102  template <typename T>
104  // AttributeHandle base_handle() const ;
105 
106 
107  template <typename T>
108  auto as() const -> const held_handle_type<held_type_from_primitive<T>()>&;
109 
110  template <HeldType Type>
111  auto as_from_held_type() const -> const held_handle_type<Type>&;
112  // returns if the held attribute uses the primitive T
113 
114 
115  // returns if the held attribute uses the primitive T
116  template <typename T>
117  bool holds() const;
118 
119  // holds basic type
120  bool holds_basic_type() const;
121 
122  // returns if the held attribute uses the held type primitive Type
123  template <HeldType Type>
124  bool holds_from_held_type() const;
125 
126  HeldType held_type() const;
127 
128  Mesh& mesh();
129  const Mesh& mesh() const;
130 
132  const HandleVariant& handle() const { return m_handle; }
138  // MutableAccessor<T> create_accessor();
139 
145  // ConstAccessor<T> create_const_accessor() const;
146  // ConstAccessor<T> create_accessor() const;
147 
148  // return the dimension of the attribute (i.e the number of values stored per simplex)
149  int64_t dimension() const;
150 
151  std::string name() const;
152 
153 
154 private:
155  Mesh* m_mesh = nullptr;
157 };
158 
159 template <typename T>
160 inline auto MeshAttributeHandle::as() const
161  -> const held_handle_type<held_type_from_primitive<T>()>&
162 {
163  return as_from_held_type<held_type_from_primitive<T>()>();
164 }
165 
166 
167 template <typename T>
168 inline bool MeshAttributeHandle::holds() const
169 {
170  return holds_from_held_type<held_type_from_primitive<T>()>();
171 }
172 
173 namespace internal {
174 template <typename T>
176 {
177  constexpr static bool value = false;
178 };
179 template <typename T>
181 {
182  constexpr static bool value = true;
183 };
184 } // namespace internal
185 
186 template <typename T>
188 {
190 }
191 
193 {
194  return std::visit(
195  [](const auto& h) noexcept -> bool {
196  return handle_type_is_basic<std::decay_t<decltype(h)>>();
197  },
198  m_handle);
199 }
200 template <MeshAttributeHandle::HeldType Type>
201 inline auto MeshAttributeHandle::as_from_held_type() const -> const held_handle_type<Type>&
202 {
203  return std::get<held_handle_type<Type>>(m_handle);
204 }
205 
206 template <MeshAttributeHandle::HeldType Type>
208 {
209  return std::holds_alternative<held_handle_type<Type>>(m_handle);
210 }
211 
212 template <typename T>
214 {
215  return held_type_from_handle<TypedAttributeHandle<T>>();
216 }
217 template <typename T>
219 {
220  if constexpr (std::is_same_v<T, TypedAttributeHandle<char>>) {
221  return HeldType::Char;
222  } else if constexpr (std::is_same_v<T, TypedAttributeHandle<double>>) {
223  return HeldType::Double;
224  } else if constexpr (std::is_same_v<T, TypedAttributeHandle<int64_t>>) {
225  return HeldType::Int64;
226  } else if constexpr (std::is_same_v<T, TypedAttributeHandle<wmtk::Rational>>) {
227  return HeldType::Rational;
228  }
229  // If a compiler complains about the potentiality of no return value then a type accepted by the
230  // HAndleVariant is not being represented properly. If the comppiler is simply unhappy to not
231  // see a return then we should hack a default return value in an else statement with an asswert
232  // :(.
233  else {
234  return HeldType::Char;
235  }
236 }
237 
239 {
240  return std::visit([](const auto& h) { return h.primitive_type(); }, m_handle);
241 }
242 template <typename T>
244 {
245  return std::get<T>(m_handle).primitive_type();
246 }
247 } // namespace wmtk::attribute
typename held_handle_type< Type >::Type held_primitive_type
const HandleVariant & handle() const
std::variant< TypedAttributeHandle< char >, TypedAttributeHandle< int64_t >, TypedAttributeHandle< double >, TypedAttributeHandle< wmtk::Rational > > HandleVariant
constexpr static HeldType held_type_from_handle()
MeshAttributeHandle(MeshAttributeHandle &&o)=default
std::variant_alternative_t< size_t(Type), HandleVariant > held_handle_type
constexpr static bool handle_type_is_basic()
auto as() const -> const held_handle_type< held_type_from_primitive< T >()> &
constexpr static HeldType held_type_from_primitive()
std::variant< char, int64_t, double, wmtk::Rational, std::tuple< char, wmtk::Rational, double > > ValueVariant
auto as_from_held_type() const -> const held_handle_type< Type > &
MeshAttributeHandle(const MeshAttributeHandle &o)=default
MeshAttributeHandle & operator=(const MeshAttributeHandle &o)=default
bool operator==(const MeshAttributeHandle &o) const
MeshAttributeHandle & operator=(MeshAttributeHandle &&o)=default
Definition: Accessor.hpp:6