TBTK
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 
48  IndexDescriptor(Format format);
49 
53  IndexDescriptor(const IndexDescriptor &indexDescriptor);
54 
58  IndexDescriptor(IndexDescriptor &&indexDescriptor);
59 
67  IndexDescriptor(const std::string &serialization, Mode mode);
68 
71 
78 
85 
89  Format getFormat() const;
90 
92 // void setDimensions(unsigned int dimensions);
93 
98  unsigned int getDimensions() const;
99 
107  void setRanges(const int *ranges, unsigned int dimensions);
108 
113 // int* getRanges();
114  std::vector<int> getRanges() const;
115 
117 // const int* getRanges() const;
118 
124  void setIndexTree(const IndexTree &indexTree);
125 
130  const IndexTree& getIndexTree() const;
131 
135  void add(const Index &index);
136 
145  int getLinearIndex(
146  const Index &index,
147  bool returnNegativeForMissingIndex = false
148  ) const;
149 
157  unsigned int getSize() const;
158 
163  bool contains(const Index &index) const;
164 
166  virtual std::string serialize(Mode mode) const;
167 private:
169  Format format;
170 
171  class NoneFormat{
172  public:
173  };
174 
175  class RangeFormat{
176  public:
178  unsigned int dimensions;
179 
181  int *ranges;
182  };
183 
184  class CustomFormat{
185  public:
187  IndexTree *indexTree;
188  };
189 
190  class DynamicFormat{
191  public:
194  IndexedDataTree<unsigned int> *indexedDataTree;
195 
197  unsigned int size;
198  };
199 
201  union Descriptor{
202  NoneFormat noneFormat;
203  RangeFormat rangeFormat;
204  CustomFormat customFormat;
205  DynamicFormat dynamicFormat;
206  };
207 
209  Descriptor descriptor;
210 };
211 
213  return format;
214 }
215 
216 /*inline void IndexDescriptor::setDimensions(unsigned int dimensions){
217  TBTKAssert(
218  format == Format::Ranges,
219  "IndexDescriptor::setDimensions()",
220  "The IndexDescriptor is not of the format Format::Ranges.",
221  ""
222  );
223  descriptor.rangeFormat.dimensions = dimensions;
224  if(descriptor.rangeFormat.ranges != NULL)
225  delete [] descriptor.rangeFormat.ranges;
226  descriptor.rangeFormat.ranges = new int[dimensions];
227 }*/
228 
229 inline unsigned int IndexDescriptor::getDimensions() const{
230  TBTKAssert(
231  format == Format::Ranges,
232  "IndexDescriptor::getDimensions()",
233  "The IndexDescriptor is not of the format Format::Ranges.",
234  ""
235  );
236  return descriptor.rangeFormat.dimensions;
237 }
238 
239 inline void IndexDescriptor::setRanges(const int *ranges, unsigned int dimensions){
240  TBTKAssert(
241  format == Format::Ranges,
242  "IndexDescriptor::setRanges()",
243  "The IndexDescriptor is not of the format Format::Ranges.",
244  ""
245  );
246  descriptor.rangeFormat.dimensions = dimensions;
247  if(descriptor.rangeFormat.ranges != NULL)
248  delete [] descriptor.rangeFormat.ranges;
249  descriptor.rangeFormat.ranges = new int[dimensions];
250  for(unsigned int n = 0; n < dimensions; n++)
251  descriptor.rangeFormat.ranges[n] = ranges[n];
252 }
253 
254 //inline int* IndexDescriptor::getRanges(){
255 inline std::vector<int> IndexDescriptor::getRanges() const{
256  TBTKAssert(
257  format == Format::Ranges,
258  "IndexDescriptor::setDimensions()",
259  "The IndexDescriptor is not of the format Format::Ranges.",
260  ""
261  );
262 // return descriptor.rangeFormat.ranges;
263 
264  std::vector<int> ranges;
265  for(unsigned int n = 0; n < descriptor.rangeFormat.dimensions; n++)
266  ranges.push_back(descriptor.rangeFormat.ranges[n]);
267 
268  return ranges;
269 }
270 
271 /*inline const int* IndexDescriptor::getRanges() const{
272  TBTKAssert(
273  format == Format::Ranges,
274  "IndexDescriptor::setDimensions()",
275  "The IndexDescriptor is not of the format Format::Ranges.",
276  ""
277  );
278  return descriptor.rangeFormat.ranges;
279 }*/
280 
282  TBTKAssert(
283  format == Format::Custom,
284  "IndexDescriptor::getIndexTree()",
285  "The IndexDescriptor is not of the format Format::Custom.",
286  ""
287  );
288 
289  return *descriptor.customFormat.indexTree;
290 }
291 
292 inline void IndexDescriptor::add(const Index &index){
293  TBTKAssert(
294  format == Format::Dynamic,
295  "IndexDescriptor::add()",
296  "The IndexDescriptor is not of the format Format::Dynamic.",
297  ""
298  );
299 
300  unsigned int dummy;
301  TBTKAssert(
302  !descriptor.dynamicFormat.indexedDataTree->get(dummy, index),
303  "IndexDescriptor::add()",
304  "The IndexDescriptor already contains the Index '"
305  << index.toString() << "'.",
306  ""
307  );
308 
309  descriptor.dynamicFormat.indexedDataTree->add(
310  descriptor.dynamicFormat.size,
311  index
312  );
313  descriptor.dynamicFormat.size++;
314 }
315 
317  const Index &index,
318  bool returnNegativeForMissingIndex
319 ) const{
320 /* TBTKAssert(
321  format == Format::Custom,
322  "IndexDescriptor::getOffset()",
323  "The IndexDescriptor is not of the format Format::Custom.",
324  ""
325  );
326 
327  return descriptor.customFormat.indexTree->getLinearIndex(
328  index,
329  IndexTree::SearchMode::MatchWildcards,
330  returnNegativeForMissingIndex
331  );*/
332  switch(format){
333  case Format::Custom:
334  return descriptor.customFormat.indexTree->getLinearIndex(
335  index,
336  IndexTree::SearchMode::MatchWildcards,
337  returnNegativeForMissingIndex
338  );
339  case Format::Dynamic:
340  {
341  unsigned int linearIndex;
342  if(
343  descriptor.dynamicFormat.indexedDataTree->get(
344  linearIndex,
345  index
346  )
347  ){
348  return linearIndex;
349  }
350  else if(returnNegativeForMissingIndex){
351  return -1;
352  }
353  else{
354  throw IndexException(
355  "IndexDescriptor::getLinearIndex()",
356  TBTKWhere,
357  "Index not included in the IndexDescriptor '"
358  + index.toString() + "'.",
359  ""
360  );
361  }
362  }
363  default:
364  TBTKExit(
365  "IndexDescriptor::getOffset()",
366  "The IndexDescriptor is not of the format"
367  " Format::Custom or Format::Dynamic.",
368  ""
369  );
370  }
371 }
372 
373 inline bool IndexDescriptor::contains(const Index &index) const{
374 /* TBTKAssert(
375  format == Format::Custom,
376  "IndexDescriptor::contains()",
377  "The IndexDescriptor is not of the format Format::Custom.",
378  ""
379  );
380 
381  if(
382  descriptor.customFormat.indexTree->getLinearIndex(
383  index,
384  IndexTree::SearchMode::StrictMatch,
385  true
386  ) == -1
387  ){
388  return false;
389  }
390  else{
391  return true;
392  }*/
393  switch(format){
394  case Format::Custom:
395  if(
396  descriptor.customFormat.indexTree->getLinearIndex(
397  index,
398  IndexTree::SearchMode::StrictMatch,
399  true
400  ) == -1
401  ){
402  return false;
403  }
404  else{
405  return true;
406  }
407  case Format::Dynamic:
408  {
409  unsigned int dummy;
410  if(
411  descriptor.dynamicFormat.indexedDataTree->get(
412  dummy,
413  index
414  )
415  ){
416  return true;
417  }
418  else{
419  return false;
420  }
421  }
422  default:
423  TBTKExit(
424  "IndexDescriptor::contains()",
425  "The IndexDescriptor is not of the format"
426  " Format::Custom or Format::Dynamic.",
427  ""
428  );
429  }
430 }
431 
432 }; //End namespace TBTK
433 
434 #endif
unsigned int getSize() const
IndexDescriptor(Format format)
IndexDescriptor & operator=(const IndexDescriptor &rhs)
Definition: IndexException.h:10
Describes the index structure of data stored for several indices.
Definition: IndexDescriptor.h:39
const IndexTree & getIndexTree() const
Definition: IndexDescriptor.h:281
Precompiler macros.
Definition: Serializable.h:40
Data structure for mapping physical indices to a linear index.
Data structure for storing data associated with an index.
std::vector< int > getRanges() const
Definition: IndexDescriptor.h:255
void setRanges(const int *ranges, unsigned int dimensions)
Definition: IndexDescriptor.h:239
virtual std::string serialize(Mode mode) const
Format
Definition: IndexDescriptor.h:42
Data structure for mapping physical indices to linear indices.
Definition: IndexTree.h:34
Flexible physical index.
Definition: Index.h:69
Definition: ModelFactory.h:35
unsigned int getDimensions() const
Definition: IndexDescriptor.h:229
Format getFormat() const
Definition: IndexDescriptor.h:212
int getLinearIndex(const Index &index, bool returnNegativeForMissingIndex=false) const
Definition: IndexDescriptor.h:316
Mode
Definition: Serializable.h:44
void add(const Index &index)
Definition: IndexDescriptor.h:292
Abstract base class for serializable objects.
void setIndexTree(const IndexTree &indexTree)
bool contains(const Index &index) const
Definition: IndexDescriptor.h:373
std::string toString() const
Definition: Index.h:282