Classdesc 3.44
multiArray.h
1/*
2 @copyright Russell Standish 2019
3 @author Russell Standish
4 This file is part of Classdesc
5
6 Open source licensed under the MIT license. See LICENSE for details.
7*/
8
9#ifndef CLASSDESC_MULTIARRAY_H
10#define CLASSDESC_MULTIARRAY_H
11#include <assert.h>
12
13namespace classdesc
14{
15 template <class T, int Rank> class MultiArray;
16 template <class T, int R> void advance(MultiArray<T,R>& a, std::ptrdiff_t n);
17
21
22 // turn a pointer back into multidimensional array
23 template <class T, int Rank>
25 {
26 T* m_data;
27 size_t dim[Rank];
28 size_t m_stride=1;
29
30 friend void advance<T,Rank>(MultiArray<T,Rank>&,std::ptrdiff_t);
31
32#if defined(__cplusplus) && __cplusplus>=201703L
33 void constructDim(size_t& d, size_t dd)
34 {
35 dim[d++]=dd;
36 m_stride*=dd;
37 }
38 template <class... Args>
39 void constructDims(size_t d, Args... args)
40 {
41 m_stride=1;
42 (constructDim(d,args),...);
43 // fold expression multiplies m_stride by one too many dimensions
44 if (d>0) m_stride/=dim[d-1];
45 }
46#else
47
48 void constructDims(size_t d, size_t d1)
49 {
50 assert(d==Rank-1);
51 dim[d]=d1;
52 }
53 template <class... Args>
54 void constructDims(size_t d, size_t d1, Args... args)
55 {
56 dim[d]=d1;
57 m_stride*=d1;
58 constructDims(d+1, args...);
59 }
60#endif
61
62 public:
63 typedef MultiArray<T,Rank-1> value_type;
64 typedef size_t size_type;
65 static const int rank=Rank;
68 template <class... Args>
69 MultiArray(T* data, Args... args): m_data(data)
70 {
71 constructDims(0, args...);
72 }
73
76 MultiArray(T* data, const size_t a_dim[]): m_data(data)
77 {
78 memcpy(dim, a_dim, sizeof(dim));
79 }
80
81 size_t size() const {return dim[Rank-1];}
82 size_t stride() const {return m_stride;}
83 const MultiArray<T,Rank-1> operator[](size_t i) const {
84 return MultiArray<T,Rank-1>(m_data+i*m_stride, dim);
85 }
86 MultiArray<T,Rank-1> operator[](size_t i) {
87 return MultiArray<T,Rank-1>(m_data+i*m_stride, dim);
88 }
89
91 bool same(const MultiArray& x) const {return m_data==x.m_data;}
92
93 struct iterator: public MultiArrayIterator
94 {
95 using difference_type=std::ptrdiff_t;
96 using value_type=MultiArray<T,Rank-1>;
97 using pointer=MultiArray<T,Rank-1>*;
98 using reference=MultiArray<T,Rank-1>&;
99 using iterator_category=std::random_access_iterator_tag;
100 using underlying_type=T;
101 static const int rank=Rank;
102
103 MultiArray<T,Rank-1> array;
104 size_t stride;
105 iterator(const MultiArray& array): array(array.m_data,array.dim),
106 stride(array.stride()) {}
107 iterator operator++() {advance(array,stride); return *this;}
108 iterator operator++(int)
109 {auto tmp=*this; advance(array,stride); return tmp;}
110 iterator operator--() {advance(array,-stride); return *this;}
111 iterator operator--(int)
112 {auto tmp=*this; advance(array,-stride); return tmp;}
113 iterator operator+=(size_t i) {advance(array,i*stride); return *this;}
114 MultiArray<T,Rank-1>& operator*() {return array;}
115 bool operator==(const iterator& x) const {return array.same(x.array);}
116 bool operator!=(const iterator& x) const {return !operator==(x);}
117 };
118 struct const_iterator: public iterator
119 {
120 const_iterator(const MultiArray& array): iterator(array) {}
121 const MultiArray<T,Rank-1>& operator*() {return iterator::operator*();}
122 };
123
124 iterator begin() {return MultiArray(*this);}
125 iterator end() {auto tmp=begin(); tmp+=dim[Rank-1]; return tmp;}
126 const_iterator begin() const {return MultiArray(*this);}
127 const_iterator end() const {auto tmp=begin(); tmp+=dim[Rank-1]; return tmp;}
128 };
129
130 template <class T>
131 class MultiArray<T, 1>: public MultiArrayBase
132 {
133 T* m_data;
134 size_t m_size;
135 friend void advance<T,1>(MultiArray<T,1>&,std::ptrdiff_t);
136
137 public:
138 typedef T value_type;
139 typedef size_t size_type;
140 static const int rank=1;
141 MultiArray(T* data, size_t size): m_data(data), m_size(size) {}
142 MultiArray(T* data, const size_t size[]): m_data(data), m_size(size[0]) {}
143 T& operator[](size_t i) {return m_data[i];}
144 const T& operator[](size_t i) const {return m_data[i];}
145 typedef T* iterator;
146 typedef const T* const_iterator;
147 T* begin() {return m_data;}
148 T* end() {return m_data+m_size;}
149 const T* begin() const {return m_data;}
150 const T* end() const {return m_data+m_size;}
151 size_t size() const {return m_size;}
152 bool same(const MultiArray& x) const {return m_data==x.m_data;}
153 };
154
155 template <class T, int N> struct is_sequence<classdesc::MultiArray<T,N>>:
156 public true_type {};
157
159 template <class T, int R>
160 void advance(MultiArray<T,R>& a, std::ptrdiff_t n)
161 {a.m_data+=n;}
162
163// template <class T, int R>
164// struct tn<MultiArray<T,R>>
165// {
166// static string name() {return "classdesc::MultiArray<"+typeName<T>()+","+std::to_string(R)+">";}
167// };
168//
169// template <class T>
170// struct tn<T,
171// typename enable_if<
172// And<is_base_of<MultiArrayIterator,T>, Not<is_same<MultiArrayIterator,T>>>,
173// void>::T>
174// {
175// static string name() {
176// return typeName<typename T::value_type>()+"::iterator";
177// }
178// };
179
180
181
182}
183
184#endif
Definition multiArray.h:25
bool same(const MultiArray &x) const
return if this refers to the same memory location as x
Definition multiArray.h:91
MultiArray(T *data, const size_t a_dim[])
Definition multiArray.h:76
MultiArray(T *data, Args... args)
Definition multiArray.h:69
Contains definitions related to classdesc functionality.
void advance(MultiArray< T, R > &a, std::ptrdiff_t n)
friended advance function for use in iterators
Definition multiArray.h:160
Definition RESTProcess_epilogue.h:159
base classes for metaprogramming
Definition multiArray.h:19
Definition multiArray.h:20
Definition multiArray.h:119
Definition multiArray.h:94
determines if T is a standard sequence container
Definition classdesc.h:302