Wildmeshing Toolkit
AttributeTransactionStack.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <Eigen/Core>
3 #include <map>
4 #include <memory>
6 #include "MapTypes.hpp"
7 
8 
9 namespace wmtk::attribute {
10 template <typename T>
11 class Attribute;
12 template <typename T, int Dim>
13 class AccessorBase;
14 namespace internal {
15 template <typename T>
17 {
18 public:
19  template <int D>
21  template <int D>
23 
24 
31 
32 
33  template <typename Derived>
34  void try_caching(int64_t index, const Eigen::MatrixBase<Derived>& value);
35  void try_caching(int64_t index, const T& value);
36 
37 
38  const T* get_value(int64_t index) const;
39 
40  // clears a stack
41  void clear();
42  int64_t size() const;
43 
44  void apply_to(Attribute<T>& attribute) const;
45 
46  // applyes to some other buffer that was passed in
47  void apply_to(const Attribute<T>& attribute, std::vector<T>& other) const;
48 
49  const std::vector<T>& buffer() const { return m_buffer; }
50  const std::vector<std::pair<size_t, size_t>>& indices() const { return m_indices; }
51 
52 
54 
55  // the starting index of each transaction
56  const std::vector<size_t>& transaction_starts() const { return m_transaction_starts; }
57  size_t buffer_end() const { return m_buffer_end; }
58  size_t indices_end() const { return m_indices_end; }
59 
60  // OLD API
61  //==========
62 
63 
64  bool empty() const;
65 
66 
67  bool writing_enabled() const;
68 
69 
71  template <
72  int D = Eigen::Dynamic,
73  int D2 = Eigen::Dynamic,
74  int TrueD = D == Eigen::Dynamic ? D2 : D>
77 
78  template <
79  int D = Eigen::Dynamic,
80  int D2 = Eigen::Dynamic,
81  int TrueD = D == Eigen::Dynamic ? D2 : D>
83  const;
85  template <int D2>
86  T& scalar_attribute(AccessorBase<T, D2>& accessor, int64_t index);
87 
89  template <int D = Eigen::Dynamic>
90  T const_scalar_attribute(const AccessorBase<T, D>& accessor, int64_t index) const;
91 
92  template <int D = Eigen::Dynamic>
94  T const_scalar_attribute(const AccessorBase<T, D>& accessor, int64_t index, int8_t offset)
95  const;
96 
97  void emplace();
98  void pop(Attribute<T>& attribute, bool preserve_changes);
99  // go to the next most historic scope
100  void change_to_next_scope();
102  // go to the scope with active data
105 
107  bool at_current_scope() const;
108 
109 
111 
112  std::vector<std::pair<size_t, size_t>>::const_iterator transaction_start_begin(
113  size_t scope_index) const;
114  std::vector<std::pair<size_t, size_t>>::const_iterator final_transaction_end() const;
115 
116  std::vector<std::pair<size_t, size_t>>::const_reverse_iterator transaction_start_rend(
117  size_t scope_index) const;
118  std::vector<std::pair<size_t, size_t>>::const_reverse_iterator final_transaction_rbegin() const;
119 
120  void update_buffer_sizes_for_add(size_t data_size);
121 
122 
123 private:
124  void apply_last_scope(Attribute<T>& attr);
125 
126 protected:
127  std::vector<T> m_buffer;
128  std::vector<std::pair<size_t, size_t>> m_indices;
129 
131 
132  // the starting index of each transaction
133  std::vector<size_t> m_transaction_starts;
134  size_t m_buffer_end;
136 };
137 
138 
139 template <typename T>
141 
142  -> std::vector<std::pair<size_t, size_t>>::const_iterator
143 {
144  return m_indices.begin() + m_transaction_starts[scope_index];
145 }
146 template <typename T>
148  -> std::vector<std::pair<size_t, size_t>>::const_iterator
149 
150 {
151  return m_indices.begin() + m_indices_end;
152 }
153 
154 template <typename T>
156  -> std::vector<std::pair<size_t, size_t>>::const_reverse_iterator
157 {
158  return std::reverse_iterator(transaction_start_begin(scope_index));
159 }
160 template <typename T>
162  -> std::vector<std::pair<size_t, size_t>>::const_reverse_iterator
163 {
164  return std::reverse_iterator(final_transaction_end());
165 }
166 
167 template <typename T>
169 {
170  return m_transaction_starts.size();
171 }
172 
173 template <typename T>
175 {
176  assert(!empty());
177  assert(at_current_scope());
178  apply_last_scope(attr);
179 }
180 
181 template <typename T>
182 template <int D, int D2, int TrueD>
184  AccessorBase<T, D2>& accessor,
185  int64_t index) -> MapResult<TrueD>
186 {
187  assert(writing_enabled());
188 
189  static_assert(D == Eigen::Dynamic || D2 == Eigen::Dynamic || D == D2);
190  auto data = accessor.template vector_attribute<TrueD>(index);
191  assert(data.cols() == 1);
192  if constexpr (D != Eigen::Dynamic) {
193  assert(data.size() == D);
194  }
195  if constexpr (D2 != Eigen::Dynamic) {
196  assert(data.size() == D2);
197  }
198  // we are typically only going to write when caching is enabled so better to optimize for this
199  if (!empty()) {
200  // assert(m_scopes.back() == *m_back);
201  try_caching(index, data);
202  // m_back->try_caching(index,data);
203  }
204  return data;
205 }
206 
207 template <typename T>
208 template <int D, int D2, int TrueD>
210  const AccessorBase<T, D2>& accessor,
211  int64_t index) const -> ConstMapResult<TrueD>
212 {
213  static_assert(D == Eigen::Dynamic || D2 == Eigen::Dynamic || D == D2);
214  if (!at_current_scope()) {
215  assert(m_current_transaction_index < m_transaction_starts.size());
216 
217  const T* ptr = get_value(index);
218  if (ptr != nullptr) {
219  const int dim = accessor.dimension();
220  auto dat = ConstMapResult<TrueD>(ptr, dim);
221  return dat;
222  }
223  }
224  return accessor.template const_vector_attribute<TrueD>(index);
225 }
226 
227 template <typename T>
228 template <int D2>
230  AccessorBase<T, D2>& accessor,
231  int64_t index) -> T&
232 {
233  assert(writing_enabled());
234  T& value = accessor.scalar_attribute(index);
235  if (!empty()) {
236  try_caching(index, value);
237  // m_active->try_caching(index, value);
238  }
239  return value;
240 }
241 
242 template <typename T>
243 template <int D2>
245  const AccessorBase<T, D2>& accessor,
246  int64_t index) const -> T
247 {
248  return const_vector_attribute<1>(accessor, index)(0);
249 }
250 template <typename T>
251 template <int D2>
253  const AccessorBase<T, D2>& accessor,
254  int64_t index,
255  int8_t offset) const -> T
256 {
257  if (!at_current_scope()) {
258  return const_vector_attribute<D2>(accessor, index)(offset);
259  } else {
260  return accessor.const_scalar_attribute(index, offset);
261  }
262 }
263 } // namespace internal
264 } // namespace wmtk::attribute
265 
This class stores data of type T in a vector.
Definition: Attribute.hpp:32
T const_scalar_attribute(const AccessorBase< T, D > &accessor, int64_t index) const
default immutable scalar access
AttributeTransactionStack & operator=(const AttributeTransactionStack &)=delete
void pop(Attribute< T > &attribute, bool preserve_changes)
bool at_current_scope() const
checks that we are viewing the active state of the attribute
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator final_transaction_rbegin() const
MapResult< TrueD > vector_attribute(AccessorBase< T, D2 > &accessor, int64_t index)
default mutable vector access
AttributeTransactionStack(const AttributeTransactionStack &)=delete
ConstMapResult< TrueD > const_vector_attribute(const AccessorBase< T, D2 > &accessor, int64_t index) const
default immutable vector access
AttributeTransactionStack(AttributeTransactionStack &&)=default
std::vector< std::pair< size_t, size_t > >::const_iterator final_transaction_end() const
void try_caching(int64_t index, const Eigen::MatrixBase< Derived > &value)
std::vector< std::pair< size_t, size_t > >::const_reverse_iterator transaction_start_rend(size_t scope_index) const
T const_scalar_attribute(const AccessorBase< T, D > &accessor, int64_t index, int8_t offset) const
specialized immutable scalar access useful for topological operations
std::vector< std::pair< size_t, size_t > > m_indices
AttributeTransactionStack & operator=(AttributeTransactionStack &&)=default
std::vector< std::pair< size_t, size_t > >::const_iterator transaction_start_begin(size_t scope_index) const
const std::vector< std::pair< size_t, size_t > > & indices() const
T & scalar_attribute(AccessorBase< T, D2 > &accessor, int64_t index)
default mutable scalar access
Definition: autodiff.h:995
typename VectorResult< T, R >::MapType MapResult
the default map type used by attributes is a map of our vector type.
Definition: MapTypes.hpp:21
typename VectorResult< T, R >::ConstMapType ConstMapResult
Definition: MapTypes.hpp:23