mf
Media Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ndcoord.h
Go to the documentation of this file.
1 #ifndef MF_NDCOORD_H_
2 #define MF_NDCOORD_H_
3 
4 #include <cstddef>
5 #include <cassert>
6 #include <array>
7 #include <initializer_list>
8 #include <functional>
9 #include <ostream>
10 #include <type_traits>
11 
12 namespace mf {
13 
15 
17 template<std::size_t Dim, typename T>
18 class ndcoord {
19  static_assert(std::is_arithmetic<T>::value, "ndcoord component type must be arithmetic");
20 
21 private:
22  std::array<T, Dim> components_;
23 
24 public:
25  using value_type = T;
26  using reference = T&;
27  using const_reference = const T&;
28  using iterator = typename std::array<T, Dim>::iterator;
29  using const_iterator = typename std::array<T, Dim>::const_iterator;
30  using size_type = std::size_t;
31  using difference_type = std::ptrdiff_t;
32 
33  ndcoord(T value = 0) noexcept { components_.fill(value); }
34 
35  template<typename It>
36  ndcoord(It begin, It end) {
37  auto out = components_.begin();
38  for(auto in = begin; in != end; ++in, ++out)
39  *out = static_cast<T>(*in);
40  }
41 
42  ndcoord(std::initializer_list<T> l) noexcept :
43  ndcoord(l.begin(), l.end()) { }
44 
45  ndcoord(const ndcoord&) = default;
46 
47  template<typename T2>
48  ndcoord(const ndcoord<Dim, T2>& coord) :
49  ndcoord(coord.begin(), coord.end()) { }
50 
51  T& operator[](std::ptrdiff_t i) noexcept {
52  assert(i >= 0 && i < Dim);
53  return components_[i];
54  }
55  const T& operator[](std::ptrdiff_t i) const noexcept {
56  assert(i >= 0 && i < Dim);
57  return components_[i];
58  }
59 
60  iterator begin() noexcept { return components_.begin(); }
61  const_iterator begin() const noexcept { return components_.cbegin(); }
62  const_iterator cbegin() const noexcept { return components_.cbegin(); }
63  iterator end() noexcept { return components_.end(); }
64  const_iterator end() const noexcept { return components_.cend(); }
65  const_iterator cend() const noexcept { return components_.cend(); }
66  size_type size() const noexcept { return Dim; }
67 
68  template<typename Unary>
69  ndcoord& transform_inplace(Unary fct) {
70  for(T& c : *this) c = fct(c);
71  return *this;
72  }
73 
74  template<typename Binary>
75  ndcoord& transform_inplace(const ndcoord& c, Binary fct) {
76  for(std::ptrdiff_t i = 0; i < Dim; ++i)
77  components_[i] = fct(components_[i], c[i]);
78  return *this;
79  }
80 
81  ndcoord& operator+=(const ndcoord& c) noexcept { return transform_inplace(c, std::plus<T>()); }
82  ndcoord& operator-=(const ndcoord& c) noexcept { return transform_inplace(c, std::minus<T>()); }
83  ndcoord& operator*=(const ndcoord& c) noexcept { return transform_inplace(c, std::multiplies<T>()); }
84  ndcoord& operator/=(const ndcoord& c) noexcept { return transform_inplace(c, std::divides<T>()); }
85 
86  ndcoord& operator*=(T val) noexcept { return operator*=(ndcoord(val)); };
87  ndcoord& operator/=(T val) noexcept { return operator/=(ndcoord(val)); };
88 
89  ndcoord operator+() noexcept { return *this; }
90  ndcoord operator-() noexcept { return transform_inplace(std::negate<T>()); }
91 
92  friend ndcoord operator+(const ndcoord& a, const ndcoord& b) noexcept
93  { return transform(a, b, std::plus<T>()); }
94  friend ndcoord operator-(const ndcoord& a, const ndcoord& b) noexcept
95  { return transform(a, b, std::minus<T>()); }
96  friend ndcoord operator*(const ndcoord& a, const ndcoord& b) noexcept
97  { return transform(a, b, std::multiplies<T>()); }
98  friend ndcoord operator/(const ndcoord& a, const ndcoord& b) noexcept
99  { return transform(a, b, std::divides<T>()); }
100 
101  friend ndcoord operator*(const ndcoord& a, T val) noexcept
102  { return a * ndcoord(val); }
103  friend ndcoord operator/(const ndcoord& a, T val) noexcept
104  { return a / ndcoord(val); }
105 
106  friend bool operator==(const ndcoord& a, const ndcoord& b) noexcept
107  { return a.components_ == b.components_; }
108  friend bool operator!=(const ndcoord& a, const ndcoord& b) noexcept
109  { return a.components_ != b.components_; }
110 
111  T product() const noexcept {
112  T prod = 1;
113  for(T c : components_) prod *= c;
114  return prod;
115  }
116 
117  const T& front() const noexcept { return components_.front(); }
118  T& front() noexcept { return components_.front(); }
119  const T& back() const noexcept { return components_.back(); }
120  T& back() noexcept { return components_.back(); }
121 
122  template<std::size_t Section_dim = Dim - 1>
123  auto tail() const noexcept {
124  ndcoord<Section_dim, T> c(begin() + (Dim - Section_dim), end());
125  return c;
126  }
127 
128  template<std::size_t Section_dim = Dim - 1>
129  auto head() const noexcept {
130  ndcoord<Section_dim, T> c(begin(), end() - (Dim - Section_dim));
131  return c;
132  }
133 
134  ndcoord<Dim - 1, T> erase(std::ptrdiff_t i) const noexcept {
135  ndcoord<Dim - 1, T> result;
136  for(std::ptrdiff_t j = 0; j < i; ++j) result[j] = components_[j];
137  for(std::ptrdiff_t j = i + 1; j < Dim; ++j) result[j - 1] = components_[j];
138  return result;
139  }
140 };
141 
142 
143 template<std::size_t Dim, typename T, typename Unary>
145  ndcoord<Dim, T> o;
146  for(std::ptrdiff_t i = 0; i < Dim; ++i) o[i] = fct(a[i]);
147  return o;
148 }
149 
150 
151 template<std::size_t Dim, typename T, typename Binary>
152 ndcoord<Dim, T> transform(const ndcoord<Dim, T>& a, const ndcoord<Dim, T>& b, Binary fct) {
153  ndcoord<Dim, T> o;
154  for(std::ptrdiff_t i = 0; i < Dim; ++i) o[i] = fct(a[i], b[i]);
155  return o;
156 }
157 
158 
159 template<std::size_t Dim, typename T>
160 std::ostream& operator<<(std::ostream& str, const ndcoord<Dim, T>& coord) {
161  str << '(';
162  for(std::ptrdiff_t i = 0; i < Dim - 1; i++) str << coord[i] << ", ";
163  str << coord.back() << ')';
164  return str;
165 }
166 
167 
168 template<typename T>
169 std::ostream& operator<<(std::ostream& str, const ndcoord<0, T>& coord) {
170  return str << "()";
171 }
172 
173 
174 template<std::size_t Dim>
176 
177 template<std::size_t Dim>
179 
180 
181 template<typename T, typename... Components>
182 auto make_ndcoord(Components... c) {
183  return ndcoord<sizeof...(Components), T>({ static_cast<T>(c)... });
184 }
185 
186 template<typename... Components>
187 auto make_ndsize(Components... c) {
188  return make_ndcoord<std::size_t>(c...);
189 }
190 
191 template<typename... Components>
192 auto make_ndptrdiff(Components... c) {
193  return make_ndcoord<std::ptrdiff_t>(c...);
194 }
195 
196 
197 template<std::size_t Dim1, std::size_t Dim2, typename T>
200  if(Dim1 + Dim2 == 0) return coord;
201  auto it = coord.begin();
202  if(Dim1 > 0) for(T c : coord1) *(it++) = c;
203  if(Dim2 > 0) for(T c : coord2) *(it++) = c;
204  return coord;
205 }
206 
207 
208 template<std::size_t Dim1, typename T, typename Int>
210  return ndcoord_cat(coord1, make_ndcoord<T>(c2));
211 }
212 
213 
214 template<std::size_t Dim2, typename T, typename Int>
216  return ndcoord_cat(make_ndcoord<T>(c1), coord2);
217 }
218 
219 
220 template<typename T>
222  return {coord[1], coord[0]};
223 }
224 
225 
226 }
227 
228 #endif
friend ndcoord operator/(const ndcoord &a, T val) noexcept
Definition: ndcoord.h:103
ndcoord & operator/=(T val) noexcept
Definition: ndcoord.h:87
const_iterator begin() const noexcept
Definition: ndcoord.h:61
ndcoord< Dim, T > transform(const ndcoord< Dim, T > &a, Unary fct)
Definition: ndcoord.h:144
const time_unit & const_reference
Definition: ndcoord.h:27
ndcoord< Dim-1, T > erase(std::ptrdiff_t i) const noexcept
Definition: ndcoord.h:134
ndcoord(const ndcoord< Dim, T2 > &coord)
Definition: ndcoord.h:48
friend ndcoord operator+(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:92
auto tail() const noexcept
Definition: ndcoord.h:123
ndcoord & operator+=(const ndcoord &c) noexcept
Definition: ndcoord.h:81
auto make_ndcoord(Components...c)
Definition: ndcoord.h:182
ndcoord & operator*=(const ndcoord &c) noexcept
Definition: ndcoord.h:83
ndcoord & transform_inplace(Unary fct)
Definition: ndcoord.h:69
typename std::array< time_unit, Dim >::iterator iterator
Definition: ndcoord.h:28
friend bool operator!=(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:108
ndcoord & operator/=(const ndcoord &c) noexcept
Definition: ndcoord.h:84
friend ndcoord operator*(const ndcoord &a, T val) noexcept
Definition: ndcoord.h:101
auto head() const noexcept
Definition: ndcoord.h:129
const_iterator end() const noexcept
Definition: ndcoord.h:64
T & front() noexcept
Definition: ndcoord.h:118
iterator begin() noexcept
Definition: ndcoord.h:60
ndcoord(It begin, It end)
Definition: ndcoord.h:36
auto make_ndsize(Components...c)
Definition: ndcoord.h:187
Vector of n-dimensional coordinates.
Definition: ndcoord.h:18
friend ndcoord operator/(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:98
T product() const noexcept
Definition: ndcoord.h:111
iterator end() noexcept
Definition: ndcoord.h:63
ndcoord operator-() noexcept
Definition: ndcoord.h:90
ndcoord< Dim1+Dim2, T > ndcoord_cat(const ndcoord< Dim1, T > &coord1, const ndcoord< Dim2, T > &coord2)
Definition: ndcoord.h:198
time_unit & reference
Definition: ndcoord.h:26
ndcoord & transform_inplace(const ndcoord &c, Binary fct)
Definition: ndcoord.h:75
time_unit value_type
Definition: ndcoord.h:25
auto make_ndptrdiff(Components...c)
Definition: ndcoord.h:192
std::ptrdiff_t difference_type
Definition: ndcoord.h:31
const T & front() const noexcept
Definition: ndcoord.h:117
size_type size() const noexcept
Definition: ndcoord.h:66
const T & back() const noexcept
Definition: ndcoord.h:119
const_iterator cend() const noexcept
Definition: ndcoord.h:65
const_iterator cbegin() const noexcept
Definition: ndcoord.h:62
T & operator[](std::ptrdiff_t i) noexcept
Definition: ndcoord.h:51
friend ndcoord operator-(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:94
ndcoord & operator*=(T val) noexcept
Definition: ndcoord.h:86
ndarray_view< 2, T > flip(const ndarray_view< 2, T > &vw)
Definition: ndarray_view.h:216
ndcoord(T value=0) noexcept
Definition: ndcoord.h:33
ndcoord & operator-=(const ndcoord &c) noexcept
Definition: ndcoord.h:82
T & back() noexcept
Definition: ndcoord.h:120
const T & operator[](std::ptrdiff_t i) const noexcept
Definition: ndcoord.h:55
ndcoord operator+() noexcept
Definition: ndcoord.h:89
ndcoord(std::initializer_list< T > l) noexcept
Definition: ndcoord.h:42
std::size_t size_type
Definition: ndcoord.h:30
typename std::array< time_unit, Dim >::const_iterator const_iterator
Definition: ndcoord.h:29
friend ndcoord operator*(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:96
friend bool operator==(const ndcoord &a, const ndcoord &b) noexcept
Definition: ndcoord.h:106