TBTK
Need a break? Support the development by playing Polarity Puzzles
IndexDescriptor.h
Go to the documentation of this file.
1 /* Copyright 2017 Kristofer Bj√∂rnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
23 #ifndef COM_DAFER45_TBTK_INDEX_DESCRIPTOR
24 #define COM_DAFER45_TBTK_INDEX_DESCRIPTOR
25 
26 #include "TBTK/IndexedDataTree.h"
27 #include "TBTK/IndexException.h"
28 #include "TBTK/IndexTree.h"
29 #include "TBTK/Serializable.h"
30 #include "TBTK/TBTKMacros.h"
31 
32 namespace TBTK{
33 
40 public:
42  enum class Format {None, Ranges, Custom, Dynamic};
43 
46 
51  IndexDescriptor(const std::vector<int> &ranges);
52 
58  IndexDescriptor(const IndexTree &indexTree);
59 
63  IndexDescriptor(const IndexDescriptor &indexDescriptor);
64 
68  IndexDescriptor(IndexDescriptor &&indexDescriptor);
69 
77  IndexDescriptor(const std::string &serialization, Mode mode);
78 
81 
88 
95 
103  friend bool operator==(
104  const IndexDescriptor &lhs,
105  const IndexDescriptor &rhs
106  );
107 
115  friend bool operator!=(
116  const IndexDescriptor &lhs,
117  const IndexDescriptor &rhs
118  );
119 
123  Format getFormat() const;
124 
129  std::vector<int> getRanges() const;
130 
135  const IndexTree& getIndexTree() const;
136 
140  void add(const Index &index);
141 
150  int getLinearIndex(
151  const Index &index,
152  bool returnNegativeForMissingIndex = false
153  ) const;
154 
162  unsigned int getSize() const;
163 
168  bool contains(const Index &index) const;
169 
171  virtual std::string serialize(Mode mode) const;
172 private:
174  Format format;
175 
176  class NoneFormat{
177  public:
178  };
179 
180  class RangeFormat{
181  public:
183  unsigned int dimensions;
184 
186  int *ranges;
187  };
188 
189  class CustomFormat{
190  public:
192  IndexTree *indexTree;
193  };
194 
195  class DynamicFormat{
196  public:
199  IndexedDataTree<unsigned int> *indexedDataTree;
200 
202  unsigned int size;
203  };
204 
206  union Descriptor{
207  NoneFormat noneFormat;
208  RangeFormat rangeFormat;
209  CustomFormat customFormat;
210  DynamicFormat dynamicFormat;
211  };
212 
214  Descriptor descriptor;
215 };
216 
217 inline bool operator!=(const IndexDescriptor &lhs, const IndexDescriptor &rhs){
218  return !(rhs == lhs);
219 }
220 
222  return format;
223 }
224 
225 inline std::vector<int> IndexDescriptor::getRanges() const{
226  TBTKAssert(
227  format == Format::Ranges,
228  "IndexDescriptor::setDimensions()",
229  "The IndexDescriptor is not of the format Format::Ranges.",
230  ""
231  );
232 
233  std::vector<int> ranges;
234  for(unsigned int n = 0; n < descriptor.rangeFormat.dimensions; n++)
235  ranges.push_back(descriptor.rangeFormat.ranges[n]);
236 
237  return ranges;
238 }
239 
241  TBTKAssert(
242  format == Format::Custom,
243  "IndexDescriptor::getIndexTree()",
244  "The IndexDescriptor is not of the format Format::Custom.",
245  ""
246  );
247 
248  return *descriptor.customFormat.indexTree;
249 }
250 
251 inline void IndexDescriptor::add(const Index &index){
252  TBTKAssert(
253  format == Format::Dynamic,
254  "IndexDescriptor::add()",
255  "The IndexDescriptor is not of the format Format::Dynamic.",
256  ""
257  );
258 
259  unsigned int dummy;
260  TBTKAssert(
261  !descriptor.dynamicFormat.indexedDataTree->get(dummy, index),
262  "IndexDescriptor::add()",
263  "The IndexDescriptor already contains the Index '"
264  << index.toString() << "'.",
265  ""
266  );
267 
268  descriptor.dynamicFormat.indexedDataTree->add(
269  descriptor.dynamicFormat.size,
270  index
271  );
272  descriptor.dynamicFormat.size++;
273 }
274 
276  const Index &index,
277  bool returnNegativeForMissingIndex
278 ) const{
279  switch(format){
280  case Format::Custom:
281  return descriptor.customFormat.indexTree->getLinearIndex(
282  index,
283  IndexTree::SearchMode::MatchWildcards,
284  returnNegativeForMissingIndex
285  );
286  case Format::Dynamic:
287  {
288  unsigned int linearIndex;
289  if(
290  descriptor.dynamicFormat.indexedDataTree->get(
291  linearIndex,
292  index
293  )
294  ){
295  return linearIndex;
296  }
297  else if(returnNegativeForMissingIndex){
298  return -1;
299  }
300  else{
301  throw IndexException(
302  "IndexDescriptor::getLinearIndex()",
303  TBTKWhere,
304  "Index not included in the IndexDescriptor '"
305  + index.toString() + "'.",
306  ""
307  );
308  }
309  }
310  default:
311  TBTKExit(
312  "IndexDescriptor::getOffset()",
313  "The IndexDescriptor is not of the format"
314  " Format::Custom or Format::Dynamic.",
315  ""
316  );
317  }
318 }
319 
320 inline bool IndexDescriptor::contains(const Index &index) const{
321  switch(format){
322  case Format::Custom:
323  if(
324  descriptor.customFormat.indexTree->getLinearIndex(
325  index,
326  IndexTree::SearchMode::StrictMatch,
327  true
328  ) == -1
329  ){
330  return false;
331  }
332  else{
333  return true;
334  }
335  case Format::Dynamic:
336  {
337  unsigned int dummy;
338  if(
339  descriptor.dynamicFormat.indexedDataTree->get(
340  dummy,
341  index
342  )
343  ){
344  return true;
345  }
346  else{
347  return false;
348  }
349  }
350  default:
351  TBTKExit(
352  "IndexDescriptor::contains()",
353  "The IndexDescriptor is not of the format"
354  " Format::Custom or Format::Dynamic.",
355  ""
356  );
357  }
358 }
359 
360 }; //End namespace TBTK
361 
362 #endif
const IndexTree & getIndexTree() const
Definition: IndexDescriptor.h:240
unsigned int getSize() const
IndexDescriptor & operator=(const IndexDescriptor &rhs)
Definition: IndexException.h:10
Describes the index structure of data stored for several indices.
Definition: IndexDescriptor.h:39
Precompiler macros.
Definition: Serializable.h:43
Data structure for mapping physical indices to a linear index.
virtual std::string serialize(Mode mode) const
std::string toString() const
Definition: Index.h:349
int getLinearIndex(const Index &index, bool returnNegativeForMissingIndex=false) const
Definition: IndexDescriptor.h:275
Data structure for storing data associated with an index.
Format
Definition: IndexDescriptor.h:42
friend bool operator==(const IndexDescriptor &lhs, const IndexDescriptor &rhs)
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:35
Physical index.
Definition: Index.h:44
Definition: Boolean.h:32
Format getFormat() const
Definition: IndexDescriptor.h:221
friend bool operator!=(const IndexDescriptor &lhs, const IndexDescriptor &rhs)
Definition: IndexDescriptor.h:217
Mode
Definition: Serializable.h:47
std::vector< int > getRanges() const
Definition: IndexDescriptor.h:225
bool contains(const Index &index) const
Definition: IndexDescriptor.h:320
void add(const Index &index)
Definition: IndexDescriptor.h:251
Abstract base class for serializable objects.