TBTK
ArrayManager.h
1 /* Copyright 2016 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_ARRAY_MANAGER
24 #define COM_DAFER45_TBTK_ARRAY_MANAGER
25 
26 #include "TBTK/Index.h"
27 #include "TBTK/Streams.h"
28 
29 namespace TBTK{
30 
37 template<typename T>
39 public:
41  static void* create(const Index &ranges);
42 
44  static void* create(const Index &ranges, T fill);
45 
47  static void destroy(void *array, const Index &ranges);
48 
50  static T* flatten(void *array, const Index &ranges);
51 
53  static void* unflatten(T *array, const Index &ranges);
54 
56  static void print(void * array, const Index &ranges);
57 private:
59  static void createRecursive(Index ranges, void **result);
60 
62  static void createRecursive(Index ranges, void **result, T fill);
63 
65  static void destroyRecursive(void *array, Index ranges);
66 
68  static void flattenRecursive(void *array, Index ranges, T *result, int offset);
69 
71  static void unflattenRecursive(T *array, Index ranges, void **result, int offset);
72 
74  static void printRecursive(void *array, Index ranges);
75 };
76 
77 template<typename T>
78 void* ArrayManager<T>::create(const Index &ranges){
79  void *result;
80 
81  createRecursive(ranges, &result);
82 
83  return result;
84 }
85 
86 template<typename T>
87 void ArrayManager<T>::createRecursive(Index ranges, void **result){
88  if(ranges.getSize() == 1){
89  *((T**)result) = new T[ranges.at(0)];
90  }
91  else{
92  *((void**)result) = new void*[ranges.at(0)];
93 
94  int currentRange = ranges.at(0);
95 // ranges.erase(ranges.begin());
96  ranges.popFront();
97  for(int n = 0; n < currentRange; n++)
98  createRecursive(ranges, &(((void**)(*result))[n]));
99  }
100 }
101 
102 template<typename T>
103 void* ArrayManager<T>::create(const Index &ranges, T fill){
104  void *result;
105 
106  createRecursive(ranges, &result, fill);
107 
108  return result;
109 }
110 
111 template<typename T>
112 void ArrayManager<T>::createRecursive(Index ranges, void **result, T fill){
113  if(ranges.getSize() == 1){
114  *((T**)result) = new T[ranges.at(0)];
115  for(int n = 0; n < ranges.at(0); n++)
116  (*((T**)result))[n] = fill;
117  }
118  else{
119  *((void**)result) = new void*[ranges.at(0)];
120 
121  int currentRange = ranges.at(0);
122 // ranges.erase(ranges.begin());
123  ranges.popFront();
124  for(int n = 0; n < currentRange; n++)
125  createRecursive(ranges, &(((void**)(*result))[n]), fill);
126  }
127 }
128 
129 template<typename T>
130 void ArrayManager<T>::destroy(void *array, const Index &ranges){
131  destroyRecursive(array, ranges);
132 }
133 
134 template<typename T>
135 void ArrayManager<T>::destroyRecursive(void *array, Index ranges){
136  if(ranges.getSize() == 1){
137  delete [] (T*)array;
138  }
139  else{
140  int currentRange = ranges.at(0);
141 // ranges.erase(ranges.begin());
142  ranges.popFront();
143  for(int n = 0; n < currentRange; n++)
144  destroyRecursive(((void**)array)[n], ranges);
145 
146  delete [] (void**)array;
147  }
148 }
149 
150 template<typename T>
151 T* ArrayManager<T>::flatten(void *array, const Index &ranges){
152  int size = 1;
153  for(unsigned int n = 0; n < ranges.getSize(); n++)
154  size *= ranges.at(n);
155 
156  T *result = new T[size];
157 
158  flattenRecursive(array, ranges, result, 0);
159 
160  return result;
161 }
162 
163 template<typename T>
164 void ArrayManager<T>::flattenRecursive(void *array, Index ranges, T *result, int offset){
165  if(ranges.getSize() == 1){
166  for(int n = 0; n < ranges.at(0); n++){
167  result[offset + n] = ((T*)array)[n];
168  }
169  }
170  else{
171  int offsetMultiplier = 1;
172  for(unsigned int n = 1; n < ranges.getSize(); n++)
173  offsetMultiplier *= ranges.at(n);
174 
175  int currentRange = ranges.at(0);
176 // ranges.erase(ranges.begin());
177  ranges.popFront();
178  for(int n = 0; n < currentRange; n++)
179  flattenRecursive(((void**)array)[n], ranges, result, offset + offsetMultiplier*n);
180  }
181 }
182 
183 template<typename T>
184 void* ArrayManager<T>::unflatten(T *array, const Index &ranges){
185  void *result;
186 
187  unflattenRecursive(array, ranges, &result, 0);
188 
189  return (void*)result;
190 }
191 
192 template<typename T>
193 void ArrayManager<T>::unflattenRecursive(T *array, Index ranges, void **result, int offset){
194  if(ranges.getSize() == 1){
195  *((T**)result) = new T[ranges.at(0)];
196  for(int n = 0; n < ranges.at(0); n++)
197  (*((T**)result))[n] = array[offset + n];
198  }
199  else{
200  *((void**)result) = new void*[ranges.at(0)];
201 
202  int offsetMultiplier = 1;
203  for(int n = 1; n < ranges.getSize(); n++)
204  offsetMultiplier *= ranges.at(n);
205 
206  int currentRange = ranges.at(0);
207 // ranges.erase(ranges.begin());
208  ranges.popFront();
209  for(int n = 0; n < currentRange; n++)
210  unflattenRecursive(array, ranges, &(((void**)(*result))[n]), offset + offsetMultiplier*n);
211  }
212 }
213 
214 template<typename T>
215 void ArrayManager<T>::print(void *array, const Index &ranges){
216  printRecursive(array, ranges);
217 }
218 
219 template<typename T>
220 void ArrayManager<T>::printRecursive(void *array, Index ranges){
221  if(ranges.getSize() == 1){
222  for(int n = 0; n < ranges.at(0); n++)
223  Streams::out << ((T*)array)[n] << "\t";
224  Streams::out << "\n";
225  }
226  else{
227  int currentRange = ranges.at(0);
228  ranges.popFront();
229  for(int n = 0; n < currentRange; n++)
230  printRecursive(((void**)array)[n], ranges);
231  Streams::out << "\n";
232  }
233 }
234 
235 }; //End of namespace TBTK
236 
237 #endif
static void destroy(void *array, const Index &ranges)
Definition: ArrayManager.h:130
Flexible physical index.
static void print(void *array, const Index &ranges)
Definition: ArrayManager.h:215
int popFront()
Definition: Index.h:371
static std::ostream out
Definition: Streams.h:36
Flexible physical index.
Definition: Index.h:69
Definition: ModelFactory.h:35
unsigned int getSize() const
Definition: Index.h:359
Definition: ArrayManager.h:38
static void * unflatten(T *array, const Index &ranges)
Definition: ArrayManager.h:184
static void * create(const Index &ranges)
Definition: ArrayManager.h:78
int & at(unsigned int n)
Definition: Index.h:351
Streams for TBTK output.
static T * flatten(void *array, const Index &ranges)
Definition: ArrayManager.h:151