FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
MultiArray.hpp
1#ifndef __FIBER_MULTIARRAY_HPP
2#define __FIBER_MULTIARRAY_HPP "Created 3.07.2004 21:42:21 by bzfbenge"
3
4#include "MultiIndex.hpp"
5#include "Iterator.hpp"
6#include "Expression.hpp"
7#include "CreativeIterator.hpp"
8
9#include <memcore/breakpoint.hpp>
10#include <vector>
11
12namespace Fiber
13{
14 using Eagle::MetaInfo;
15
28template <Dims_t N, class T>
30{
31private:
32 MultiIndex<N> dimensions;
33
34 using CreativeIterator<T>::myDataCreator;
35
36public:
38
40 using CreativeIterator<T>::ptr;
41
43 using typename Base_t::component_t;
44
46static constexpr Dims_t Dims = N;
47
48// enum { Dims = N };
49
51 typedef T value_type;
52
55
58
61 typedef MultiArrayBase<N-1,T> Slice_t;
62
64
67 : CreativeIterator<T>( Extension.size(), data, Crec)
68 , dimensions(Extension)
69 {}
70
73 : Base_t(data, TheCreator)
74 , dimensions(Extension)
75 {
76 if (Extension.size() < this->count() )
77 {
78 this->setCount( dimensions.size() );
79 }
80 }
81
84 : Base_t(MAB)
85 , dimensions(MAB.dimensions)
86 {}
87
89 constexpr unsigned long memsize() const
90 {
91 return dimensions.size() * sizeof(T);
92 }
93
95 constexpr const Storage_t&storage() const
96 {
97 return (*this);
98 }
99
101 constexpr const MultiIndex<Dims>&Size() const
102 {
103 return dimensions;
104 }
105
107 void Resize(T*data, const MultiIndex<N>&D)
108 {
109 this->dimensions = D;
110 this->SetNewData(data, dimensions.size() );
111
112 }
113
114
117 {
118 return dimensions.size();
119 }
120
123 {
124 return getElement(I);
125 }
126
127#ifdef __cpp_multidimensional_subscript
128 template<typename I0, typename I1, typename... I>
129 auto operator[](I0 i0, I1 i1, const I&... indices) const
130 {
131 static_assert( N == sizeof...(I)+2, "Wrong number of multidimensional arguments." );
132 return getElement( MIndex(i0, i1, indices... ) );
133 }
134#endif
135
140 {
141 if (!ptr() )
142 {
143 Assertion( myDataCreator, "Accessing MultiArray without storage!" );
144
145 index_t i = I.maxidx();
146 Slice_t mySlice( myDataCreator->slice(Dims-1, i), dimensions.subidx(), myDataCreator);
147 MultiIndex<Dims-1> sI = I.subidx();
148
149 return mySlice[ sI ];
150 }
151
152 return Base_t::operator[]( I.linear(dimensions) );
153 }
154
163 {
164 const MultiIndex<Dims-1>&SubSize = dimensions.subidx();
165 assert(i>=0 && i < dimensions.maxidx() );
166
167 if (!ptr() )
168 {
169 assert(myDataCreator);
170
171 return Slice_t( myDataCreator->slice(Dims-1, i), SubSize, myDataCreator);
172 }
173
174 // Create subarray from iterator here, no on-demand creator here (last argument 0)
175
176 return Slice_t( *reinterpret_cast<const Iterator<T>*>(this) + index_t(i*SubSize.size()), SubSize, 0 );
177 }
178
179 Slice_t operator[](index_t i) const
180 {
181 return slice(i);
182 }
183
184 reference_t first() const
185 {
186 MultiIndex<N> I;
187 for(std::size_t i=0; i<N; i++)
188 I[i] = 0;
189
190 return (*this)[ I ];
191 }
192
193
194 reference_t last() const
195 {
196 MultiIndex<N> I;
197 for(std::size_t i=0; i<N; i++)
198 {
199 if (dimensions[i]<1)
200 I[i] = 0;
201 else
202 I[i] = dimensions[i] - 1;
203 }
204
205 return (*this)[ I ];
206 }
207};
208
221template <class T>
222class MultiArrayBase<1,T> : public CreativeIterator<T>
223{
224 using CreativeIterator<T>::myDataCreator;
225
226public:
227 using CreativeIterator<T>::ptr;
228
230
232 using typename Base_t::component_t;
233
234 enum { Dims = 1 };
235
236 MultiIndex<Dims> dimensions;
237
238 using Iterator<T>::count;
239
240 typedef T value_type;
241
244
245 typedef typename Iterator<T>::reference_t reference_t;
246
249 : Base_t(data, Crec)
250 , dimensions( Extension )
251 {
252 if (count() > dimensions.size() )
253 this->setCount( dimensions.size() );
254 }
255
258 : CreativeIterator<T>( Extension.size(), data, Crec)
259 , dimensions(Extension)
260 {}
261
263 const Storage_t&storage() const
264 {
265 return *this;
266 }
267
269 void Resize(T*newData, const MultiIndex<1>&D)
270 {
271 this->dimensions = D;
272 this->SetNewData(newData, D.size() );
273 }
274
276 void Resize(T*newData, const index_t&D)
277 {
278 Resize(newData, MIndex(D) );
279 }
280
282 unsigned long memsize() const
283 {
284 return dimensions.size() * sizeof(T);
285 }
286
287 Iterator<T> getData(index_t i) const
288 {
289 return (*this)+i;
290 }
291
293 const MultiIndex<Dims>&Size() const
294 {
295 return dimensions;
296 }
297
301 {
302 return dimensions.size();
303 }
304
308 {
309 if (myDataCreator)
310 return myDataCreator->getElement(i);
311
312 return storage()[ i ];
313 }
314
318 {
319 if (myDataCreator)
320 return myDataCreator->getElement(i);
321
322 return storage()[ i ];
323 }
324
327 {
328 index_t i = I.maxidx();
329 return (*this)[ i ];
330 }
331
334 {
335 return (*this)[ I.maxidx() ];
336 }
337
338 const reference_t slice(index_t i) const
339 {
340 return (*this)[i];
341 }
342
344 const reference_t first() const
345 {
346 return (*this)[ 0 ];
347 }
348
350 const reference_t last() const
351 {
352 index_t I = 0;
353 if (dimensions[0]>1)
354 I = dimensions[0] - 1;
355
356 return (*this)[ I ];
357 }
358};
359
360
361#ifdef __clang__
362#warning CLANG HAS BUG https://bugs.llvm.org/show_bug.cgi?id=42757
363#define INDEX_SEQUENCE_BUG
364#endif
365
366#ifdef INDEX_SEQUENCE_BUG
367template <Dims_t N, class T>
368class MultiArray;
369#else
370template <Dims_t N, class T, class = std::make_index_sequence<N>>
372#endif
373
386#ifdef INDEX_SEQUENCE_BUG
387template <Dims_t N, class T>
388class MultiArray : public MultiArrayBase<N,T>
389#else
390template <Dims_t N, class T, std::size_t... Is>
391class MultiArray<N, T, std::index_sequence<Is...>> : public MultiArrayBase<N,T>
392#endif
393{
394public:
396
397 typedef typename Base_t::value_type value_type;
398
399 typedef MultiArray MultiArray_t;
400
401 using Base_t::Size;
402 using Base_t::slice;
403 using Base_t::operator[];
404 using Base_t::ptr;
405
406 typedef typename Base_t::ValueBase_t ValueBase_t;
407 typedef typename Base_t::component_t component_t;
408
410
412
418 : Base_t( Iterator<T>(Sz.size(), data), Sz, 0)
419 {}
420
428
434 : Base_t(data, Sz, 0)
435 {}
436
438 : Base_t(MA)
439 {}
440
441 MultiArray(const Base_t&MA)
442 : Base_t(MA)
443 {}
444
445 MultiArrayBase_t arraybase() const
446 {
447 return MultiArrayBase_t( this->getArrayIterator(), Size() );
448// return MultiArrayBase_t(array_iterator(*this), Size() );
449 }
450
456 operator MultiArrayBase_t() const
457 {
458 return arraybase();
459 }
460
461
462 MultiArrayComponent_t component(int i) const
463 {
464 return MultiArrayComponent_t(this->getComponent(i), Size() );
465 }
466
469
470 typedef typename MultiArray<N-1,T>::MultiArray_t Hyperslab_t;
471
484 Hyperslab_t hyperslab(index_t i) const
485 {
486 return Hyperslab_t( slice(i) );
487 }
488
489#ifndef INDEX_SEQUENCE_BUG
490 T&operator()(decltype(Is, index_t{})... args)
491 {
492 return this->getElement( Fiber::MIndex(args...) );
493 }
494
495 const T&operator()(decltype(Is, index_t{})... args) const
496 {
497 return this->getElement( Fiber::MIndex(args...) );
498 }
499#endif
500};
501
502
503template <class T>
504class MultiArray<0, T>
505{
506public:
507 typedef T MultiArray_t;
508
509 typedef typename MetaInfo<T>::element_t component_t;
510
513
514 typedef typename META::IF< MetaInfo<T>::MULTIPLICITY == 1,
515 component_t, FixedArray_t>::result ValueBase_t;
516
518
520
521
522 void *ptr() const { return 0; }
523};
524
525
526template <int I> struct MultiArrayOutStreamSeparator
527{
528 enum { begin = '{', end = '}' };
529};
530
531template <> struct MultiArrayOutStreamSeparator<1>
532{
533 enum { begin = 0, end = ' ' };
534};
535
536template <> struct MultiArrayOutStreamSeparator<2>
537{
538 enum { begin ='(', end = ')' };
539};
540
541template <> struct MultiArrayOutStreamSeparator<3>
542{
543 enum { begin = 0, end = '\n' };
544};
545
546// MSVC GCC G++ SGI C++
547#if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || _CPP_IOSTREAM || defined(__SGI_STL_IOSTREAM) || defined(__clang__)
548
549template <int N, class T>
550std::ostream&operator<<(std::ostream&out, const MultiArray<N,T>&M)
551{
552 for(index_t k=0; k<M.Size()[N-1]; k++)
553 {
556
557 out << M[k]
559 }
560 return out;
561}
562
563#endif
564
565
566template <class Operator>
568{
569
570 template <int D, class Data, class Data1, class Data2>
571 static void ternary(const MultiArray<D,Data >&p,
572 const MultiArray<D,Data1>&q,
573 const MultiArray<D,Data2>&r)
574 {
577 array_iterator(r) );
578 }
579};
580
584template <int N, class T>
585struct MultiArraySTLVector : public std::vector<T>, public MultiArray<N,T>
586{
588 : std::vector<T>( Sz.size() )
589 , MultiArray<N,T>( &*this->begin(), Sz )
590 {}
591};
592
594template <int N, class T>
595[[deprecated("Warning: Converting an entire MultiArray to a string!")]]
596inline std::string mkString(const Fiber::MultiArray<N, T>&M)
597{
599
600 for(auto I : M.Size())
601 {
602 retval += " " + to_string(I) + ": " + to_string(M[I]) + "\n";
603 }
604
605 return retval;
606}
607
608} /* namespace Fiber */
609
610
611namespace std
612{
613
619template <int N, class T>
620[[deprecated("Warning: Converting an entire MultiArray to a string!")]]
621inline string to_string(const Fiber::MultiArray<N, T>&M)
622{
623string retval;
624
625 for(auto I : M.Size())
626 {
627 retval += " " + to_string(I) + ": " + to_string(M[I]) + "\n";
628 }
629
630 return retval;
631}
632
633
634} // std
635
636
637#endif /* __Fiber_MULTIARRAY_HPP */
basic_ostream< char > ostream
valarray< size_t > size() const
basic_string< char > string
constexpr const_iterator begin() const noexcept
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
void SetNewData(T *newData, index_t newLength)
Change the stored data chunk to a new location and length.
Definition vector/Iterator.hpp:233
T & getElement(index_t i, int c) const
Element access (no range check!).
Definition vector/Iterator.hpp:285
T * ptr(int c=0) const
Return pointer to data, which is good for C interface, but otherwise, avoid that.
Definition vector/Iterator.hpp:266
void setCount(index_t size)
Set the maximally allowed count, i.e.
Definition HyperslabParameters.hpp:156
index_t count() const
Return the number of steps which can be traversed through this ElementIterator.
Definition HyperslabParameters.hpp:147
Implementation of an Iterator to a sequence of elements, which might be contiguous or a projection of...
Definition vector/Iterator.hpp:525
T & operator[](index_t i) const
Access an element of the array, writeable.
Definition vector/Iterator.hpp:712
const reference_t first() const
Return reference to the first element.
Definition MultiArray.hpp:344
const MultiIndex< Dims > & Size() const
Return the number of elements in each direction, a multidimensional index.
Definition MultiArray.hpp:293
unsigned long memsize() const
Return the number of bytes occupied by this MultiArray.
Definition MultiArray.hpp:282
const Storage_t & storage() const
Reference to the stored data.
Definition MultiArray.hpp:263
MultiArrayBase(const Iterator< T > &data, const MultiIndex< Dims > &Extension, DataCreator< T > *Crec)
One-dimensional constructor.
Definition MultiArray.hpp:248
void Resize(T *newData, const index_t &D)
Change internally stored memory layout, shortcut for 1D.
Definition MultiArray.hpp:276
const reference_t operator[](const MultiIndex< 1 > &I) const
Index via multidimensional index, readonly.
Definition MultiArray.hpp:326
index_t nElements() const
Return the total number of elements This is equivalent to calling Size().size()
Definition MultiArray.hpp:300
MultiArrayBase(T *data, const MultiIndex< 1 > &Extension, DataCreator< T > *Crec)
Constructor.
Definition MultiArray.hpp:257
const reference_t operator[](index_t i) const
Return a stored element accessed by a linear index possible invoking the local creator if such exists...
Definition MultiArray.hpp:307
reference_t operator[](const MultiIndex< 1 > &I)
Access via multidimensional index, modifyable.
Definition MultiArray.hpp:333
Iterator< T > Storage_t
The layout of the stored data.
Definition MultiArray.hpp:243
const reference_t last() const
Return last element in the array.
Definition MultiArray.hpp:350
void Resize(T *newData, const MultiIndex< 1 > &D)
Change internally stored memory layout.
Definition MultiArray.hpp:269
reference_t operator[](index_t i)
Return a reference to a stored element via a linear index, possible invoking the local creator if suc...
Definition MultiArray.hpp:317
A generic multidimensional array is a one-dimensional pointer together with a specification of the ex...
Definition MultiArray.hpp:30
Slice_t slice(index_t i) const
Extract an N-1 dimensional slice of the current data set for read-only access.
Definition MultiArray.hpp:162
constexpr const Storage_t & storage() const
Reference to the stored data.
Definition MultiArray.hpp:95
void Resize(T *data, const MultiIndex< N > &D)
Change stored dimensionality, use with care.
Definition MultiArray.hpp:107
static constexpr Dims_t Dims
The dimensions of this array.
Definition MultiArray.hpp:46
Iterator< T > SliceStorge_t
The storage type of a subslice.
Definition MultiArray.hpp:57
Iterator< T > Storage_t
The layout of the stored data.
Definition MultiArray.hpp:54
T value_type
The type of each element in this array.
Definition MultiArray.hpp:51
MultiArrayBase(const MultiArrayBase &MAB)
Copy Constructor.
Definition MultiArray.hpp:83
reference_t operator[](const MultiIndex< N > &I) const
multidimensional element access
Definition MultiArray.hpp:122
index_t nElements() const
number of elements in here
Definition MultiArray.hpp:116
MultiArrayBase(T *data, const MultiIndex< Dims > &Extension, DataCreator< T > *Crec)
Constructor.
Definition MultiArray.hpp:66
constexpr unsigned long memsize() const
Return the number of bytes occupied by this MultiArray.
Definition MultiArray.hpp:89
reference_t getElement(const MultiIndex< N > &I) const
Element access.
Definition MultiArray.hpp:139
MultiArrayBase(const Iterator< T > &data, const MultiIndex< Dims > &Extension, DataCreator< T > *TheCreator=0)
Constructor.
Definition MultiArray.hpp:72
MultiArrayBase< N-1, T > Slice_t
The type of a slice of this array All data in this slice are still contiguous.
Definition MultiArray.hpp:61
constexpr const MultiIndex< Dims > & Size() const
Dimensionality.
Definition MultiArray.hpp:101
Iterator< T > SliceStorage_t
The layout of the stored data within a slice.
Definition MultiArray.hpp:468
MultiArray(const MultiIndex< N > &Sz, DataCreator< T > *Crec)
Construct multidimensional array with callback for data creation when a certain slice is accessed (de...
Definition MultiArray.hpp:425
MultiArray(T *data, const MultiIndex< N > &Sz)
Construct a multidimensional array from a data pointer and size specification.
Definition MultiArray.hpp:417
MultiArray(const Iterator< T > &data, const MultiIndex< N > &Sz)
Construct multidimensional array from iterator object and dimensionality.
Definition MultiArray.hpp:433
Hyperslab_t hyperslab(index_t i) const
Extract an N-1 dimensional hyperslab of the current data set.
Definition MultiArray.hpp:484
Definition MultiArray.hpp:371
A recursively defined multidimensional index.
Definition MultiIndex.hpp:331
Anemone_Context_t operator<<(Anemone &A, VRenderContext &VC)
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
Iterator< Type > array_iterator(const Iterator< Type > &It)
Specialization of the array_iterator() function for Iterators on what is already a FixedArray.
Definition vector/Iterator.hpp:1268
IndexTypeConfig< sizeof(void *)>::index_t index_t
Define the index type as according to the size of a pointer, i.e.
Definition Index.hpp:22
std::string to_string(const span< char > &s)
STL namespace.
static void ternary(const Iterator< Data > &p, const Iterator< Data1 > &q, const Iterator< Data2 > &r)
Definition Expression.hpp:76
Definition MultiArray.hpp:568
Definition MultiArray.hpp:527
A multidimensional array for data that are stored in an STL vector<>.
Definition MultiArray.hpp:586