CNORXZ
Container with Native Operation Routines and Expressions
Loading...
Searching...
No Matches
op_types.cc.h
Go to the documentation of this file.
1// -*- C++ -*-
12#ifndef __cxz_op_types_cc_h__
13#define __cxz_op_types_cc_h__
14
15#include "op_types.h"
16#include "op_utility.h"
18
19namespace CNORXZ
20{
21
22 /*====================+
23 | COpInterface |
24 +====================*/
25
26 template <class OpT>
27 template <class F, class IndexT>
28 constexpr decltype(auto) COpInterface<OpT>::c(F&& f, const Sptr<IndexT>& ind) const
29 {
30 return contraction(std::forward<F>(f), THIS().r(), ind);
31 }
32
33 template <class OpT>
34 template <class IndexT>
35 constexpr decltype(auto) COpInterface<OpT>::c(const Sptr<IndexT>& ind) const
36 {
37 return contraction([](auto& a, const auto& b) { a += b; },
38 THIS(), ind);
39 }
40
41 template <class OpT>
42 template <class F, class... Args>
43 constexpr decltype(auto) COpInterface<OpT>::o(F&& f, Args&&... args) const
44 {
45 return operation(std::forward<F>(f), THIS().r(), args...);
46 }
47
48
49 /*===================+
50 | OpInterface |
51 +===================*/
52
53 template <class OpT>
54 template <class IndexT, class F, class... Args>
55 constexpr decltype(auto) OpInterface<OpT>::ax(const Sptr<IndexT>& ind, F&& f, const Args&... args)
56 {
57 return ind->ifor( operation(f, OI::THIS().r(), args...), NoF {} );
58 }
59
60 template <class OpT>
61 template <class IndexT, class F, class... Args>
62 inline void OpInterface<OpT>::a(const Sptr<IndexT>& ind, F&& f, const Args&... args)
63 {
64 ax(ind, f, args...)();
65 }
66
67
68 /*=============+
69 | COpRoot |
70 +=============*/
71
72 template <typename T, class IndexT>
74 mData(a.data()+ind->pos()),
75 mIndex(ind)
76 {}
77
78 template <typename T, class IndexT>
79 constexpr COpRoot<T,IndexT>::COpRoot(const T* data, const Sptr<IndexT>& ind) :
80 mData(data+ind->pos()),
81 mIndex(ind)
82 {}
83
84 template <typename T, class IndexT>
86 {
87 mData = data+ind->pos();
88 mIndex = ind;
89 return *this;
90 }
91
92 template <typename T, class IndexT>
93 template <class PosT>
94 constexpr decltype(auto) COpRoot<T,IndexT>::operator()(const PosT& pos) const
95 {
96 if constexpr(is_epos_type<PosT>::value){
97 return vreg(mData,pos); // distinguish between consecutive/non-consecutive
98 }
99 else {
100 return mData[pos.val()];
101 }
102 }
103
104 template <typename T, class IndexT>
105 constexpr decltype(auto) COpRoot<T,IndexT>::operator()() const
106 {
107 return mData[0];
108 }
109
110 template <typename T, class IndexT>
111 template <SizeT I>
112 constexpr decltype(auto) COpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
113 {
114 return mIndex->stepSize(id);
115 }
116
117 template <typename T, class IndexT>
119 {
120 return mData;
121 }
122
123 template <typename T, class IndexT>
124 constexpr decltype(auto) coproot(const CArrayBase<T>& a, const Sptr<IndexT>& ind)
125 {
126 return COpRoot<T,IndexT>(a, ind);
127 }
128
129 template <typename T, class IndexT>
130 constexpr decltype(auto) coproot(const T* a, const Sptr<IndexT>& ind)
131 {
132 return COpRoot<T,IndexT>(a, ind);
133 }
134
135 /*=============+
136 | POpRoot |
137 +=============*/
138
139 template <class IndexT, class Op>
140 constexpr POpRoot<IndexT,Op>::POpRoot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op) :
141 mIndex(ind),
142 mFp(1,parts),
143 mOp(std::forward<Op>(op))
144 {}
145
146 template <class IndexT, class Op>
147 template <class PosT>
148 constexpr decltype(auto) POpRoot<IndexT,Op>::operator()(const PosT& pos) const
149 {
150 return mOp(mFp(pos));
151 }
152
153 template <class IndexT, class Op>
154 constexpr decltype(auto) POpRoot<IndexT,Op>::operator()() const
155 {
156 return mOp(mFp(SPos<0>()));
157 }
158
159 template <class IndexT, class Op>
160 template <SizeT I>
161 constexpr decltype(auto) POpRoot<IndexT,Op>::rootSteps(const IndexId<I>& id) const
162 {
163 return mIndex->stepSize(id);
164 }
165
166 template <class IndexT, class Op>
167 constexpr decltype(auto) POpRoot<IndexT,Op>::data() const
168 {
169 return mOp->data();
170 }
171
172 template <class IndexT, class Op>
173 constexpr decltype(auto) poproot(const Sptr<IndexT>& ind, const SizeT* parts, Op&& op)
174 {
175 return POpRoot(ind, parts, std::forward<Op>(op));
176 }
177
178 /*==============+
179 | OpCont |
180 +==============*/
181
182 template <typename T, class IndexT>
184 mIndex(ind),
185 mC(std::make_shared<Vector<T>>(mIndex->pmax().val()))
186 {}
187
188 template <typename T, class IndexT>
190 {
191 mIndex = ind;
192 if(mC.size() != mIndex->pmax().val()){
193 mC.resize(mIndex->pmax().val());
194 }
195 return *this;
196 }
197
198 template <typename T, class IndexT>
200 const Vector<T>& c)
201 {
202 init(ind);
203 CXZ_ASSERT(c.size() == mC.size(),
204 "size-mismatch: expected " << mC.size() << ", got " << c.size());
205 std::transform(c.begin(), c.end(), mC.begin(), [](const auto& x) { return x; } );
206 return *this;
207 }
208
209 template <typename T, class IndexT>
210 constexpr decltype(auto) OpCont<T,IndexT>::r()
211 {
212 return OpRoot<T,IndexT>(data(), mIndex);
213 }
214
215 template <typename T, class IndexT>
216 constexpr decltype(auto) OpCont<T,IndexT>::r() const
217 {
218 return COpRoot<T,IndexT>(data(), mIndex);
219 }
220
221 template <typename T, class IndexT>
222 template <class Op>
224 {
225 // TODO: build and execute assign expression forwarding outer index
226 // if a1 and a2 are non-expression types (like it is the case now),
227 // just do what is currently implemented
228 OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
229 return *this;
230 }
231
232 template <typename T, class IndexT>
233 template <class Op>
235 {
236 OI::a(mIndex, [](auto& a1, const auto& a2) { a1 += a2; }, o);
237 return *this;
238 }
239
240 template <typename T, class IndexT>
242 {
243 OI::a(mIndex, [](auto& a1, const auto& a2) { a1 = a2; }, o);
244 return *this;
245 }
246
247 template <typename T, class IndexT>
248 template <class PosT>
249 constexpr decltype(auto) OpCont<T,IndexT>::operator()(const PosT& pos) const
250 {
251 if constexpr(is_epos_type<PosT>::value){
253 return vreg(mC.data(),pos);
254 }
255 else {
256 // non-consecutive data cannot be directly accessed
257 // so there is no non-const (write) access!
258 return vreg(const_cast<const T*>(mC.data()),pos);
259 }
260 }
261 else {
262 return mC[pos.val()];
263 }
264 }
265
266 template <typename T, class IndexT>
267 constexpr decltype(auto) OpCont<T,IndexT>::operator()() const
268 {
269 return mC[0];
270 }
271
272 template <typename T, class IndexT>
273 template <SizeT I>
274 constexpr decltype(auto) OpCont<T,IndexT>::rootSteps(const IndexId<I>& id) const
275 {
276 return mIndex->stepSize(id);
277 }
278
279 template <typename T, class IndexT>
281 {
282 return mC.data();
283 }
284
285 template <typename T, class IndexT>
287 {
288 return mC.data();
289 }
290
291 /*==============+
292 | OpRoot |
293 +==============*/
294
295 template <typename T, class IndexT>
297 mData(a.data()+ind->pos()),
298 mIndex(ind)
299 {}
300
301 template <typename T, class IndexT>
302 constexpr OpRoot<T,IndexT>::OpRoot(T* data, const Sptr<IndexT>& ind) :
303 mData(data+ind->pos()),
304 mIndex(ind)
305 {}
306
307 template <typename T, class IndexT>
309 {
310 mData = data+ind->pos();
311 mIndex = ind;
312 return *this;
313 }
314
315 template <typename T, class IndexT>
316 template <class Op>
318 {
319 OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
320 return *this;
321 }
322
323 template <typename T, class IndexT>
324 template <class Op>
326 {
327 OI::a(mIndex, [](auto& a, const auto& b) { a += b; }, o);
328 return *this;
329 }
330
331 template <typename T, class IndexT>
333 {
334 OI::a(mIndex, [](auto& a, const auto& b) { a = b; }, o);
335 return *this;
336 }
337
338 template <typename T, class IndexT>
339 template <class PosT>
340 constexpr decltype(auto) OpRoot<T,IndexT>::operator()(const PosT& pos) const
341 {
342 if constexpr(is_epos_type<PosT>::value){
344 return vreg(mData,pos);
345 }
346 else {
347 // non-consecutive data cannot be directly accessed
348 // so there is no non-const (write) access!
349 return vreg(const_cast<const T*>(mData),pos);
350 }
351 }
352 else {
353 return mData[pos.val()];
354 }
355 }
356
357 template <typename T, class IndexT>
358 constexpr decltype(auto) OpRoot<T,IndexT>::operator()() const
359 {
360 return mData[0];
361 }
362
363 template <typename T, class IndexT>
364 template <SizeT I>
365 constexpr decltype(auto) OpRoot<T,IndexT>::rootSteps(const IndexId<I>& id) const
366 {
367 return mIndex->stepSize(id);
368 }
369
370 template <typename T, class IndexT>
372 {
373 return mData;
374 }
375
376 template <typename T, class IndexT>
377 constexpr decltype(auto) oproot(ArrayBase<T>& a, const Sptr<IndexT>& ind)
378 {
379 return OpRoot<T,IndexT>(a, ind);
380 }
381
382 /*=================+
383 | Operation |
384 +=================*/
385
386 template <class F, class... Ops>
387 constexpr Operation<F,Ops...>::Operation(F&& f, const Ops&... ops) :
388 mOps(ops...),
389 mF(std::forward<F>(f))
390 {}
391
392 template <class F, class... Ops>
393 template <class PosT>
394 constexpr decltype(auto) Operation<F,Ops...>::operator()(const PosT& pos) const
395 {
396 return pos_unpack_args(mF, pos, mOps);
397 }
398
399 template <class F, class... Ops>
400 constexpr decltype(auto) Operation<F,Ops...>::operator()() const
401 {
402 return exec(std::make_index_sequence<sizeof...(Ops)>{});
403 }
404
405 template <class F, class... Ops>
406 template <SizeT I>
407 constexpr decltype(auto) Operation<F,Ops...>::rootSteps(const IndexId<I>& id) const
408 {
409 return rootStepsi(id, std::make_index_sequence<sizeof...(Ops)>{});
410 }
411
412 template <class F, class... Ops>
413 template <SizeT... Is>
414 constexpr decltype(auto) Operation<F,Ops...>::exec(std::index_sequence<Is...> is) const
415 {
416 return mF( std::get<Is>(mOps)() ... );
417 }
418
419 template <class F, class... Ops>
420 template <SizeT I, SizeT... Is>
421 constexpr decltype(auto) Operation<F,Ops...>::rootStepsi(const IndexId<I>& id,
422 std::index_sequence<Is...> is) const
423 {
424 return ( std::get<Is>(mOps).rootSteps(id) << ... );
425 }
426
427 template <class F, class... Ops>
428 constexpr decltype(auto) operation(F&& f, const Ops&... ops)
429 {
430 return Operation<F,Ops...>(std::forward<F>(f), ops...);
431 }
432
433 template <class Tar, class Src>
434 constexpr decltype(auto) assignxpr(const Tar& tar, const Src& src)
435 {
436 static_assert(is_xpr<Tar>::value, "expected expression");
437 if constexpr(is_xpr<Src>::value){
438 return operation([](auto& a, const auto& b) { a = b; }, tar, src);
439 }
440 else {
441 return operation([&](auto& a) { a = src; }, tar);
442 }
443 }
444
445 template <class Tar, class Src>
446 constexpr decltype(auto) assignxpr(Tar& tar, const Src& src)
447 {
448 if constexpr(is_xpr<Tar>::value){
449 if constexpr(is_xpr<Src>::value){
450 return operation([](auto& a, const auto& b) { a = b; }, tar, src);
451 }
452 else {
453 return operation([&](auto& a) { a = src; }, tar);
454 }
455 }
456 else {
457 if constexpr(is_xpr<Src>::value){
458 return operation([&](const auto& b) { tar = b; }, src);
459 }
460 else {
461 return operation([&]() { tar = src; });
462 }
463 }
464 }
465
466 /*===================+
467 | Contraction |
468 +===================*/
469
470 template <class CXpr>
472 mCXpr(cxpr)
473 {}
474
475 template <class CXpr>
476 template <class PosT>
477 constexpr decltype(auto) Contraction<CXpr>::operator()(const PosT& pos) const
478 {
479 return mCXpr(pos);
480 }
481
482 template <class CXpr>
483 constexpr decltype(auto) Contraction<CXpr>::operator()() const
484 {
485 return mCXpr();
486 }
487
488 template <class CXpr>
489 template <SizeT I>
490 constexpr decltype(auto) Contraction<CXpr>::rootSteps(const IndexId<I>& id) const
491 {
492 return mCXpr.rootSteps(id);
493 }
494
495 template <class F, class Op, class IndexT>
496 constexpr decltype(auto) contraction(F&& f, Op&& op, const Sptr<IndexT>& i)
497 {
498 typedef decltype(i->ifor( op, f )) CXprT; // TODO: implement ifor with func arg!!!
499 return Contraction<CXprT>( i->ifor( op, f ) );
500 }
501
502 /*======================+
503 | various functions |
504 +======================*/
505
506 template <class IndexT>
507 constexpr decltype(auto) indexOp(const Sptr<IndexT>& i)
508 {
509 return i->xpr(i);
510 }
511
512
513}
514
515#endif
#define CXZ_ASSERT(statement, errmsg)
Definition assert.h:40
constexpr COpRoot & init(const T *data, const Sptr< IndexT > &ind)
Definition op_types.cc.h:85
constexpr COpRoot()=default
const T * data() const
constexpr Contraction()=default
constexpr decltype(auto) rootSteps(const IndexId< I > &id) const
constexpr OpCont & operator+=(const Op &in)
constexpr OpCont & operator=(const Op &in)
constexpr OpCont & init(const Sptr< IndexT > &ind)
constexpr OpCont()=default
void a(const Sptr< IndexT > &ind, F &&f, const Args &... args)
Definition op_types.cc.h:62
T * data() const
constexpr OpRoot & operator+=(const Op &in)
constexpr OpRoot()=default
constexpr OpRoot & init(T *data, const Sptr< IndexT > &ind)
constexpr OpRoot & operator=(const Op &in)
constexpr Operation()=default
constexpr decltype(auto) data() const
constexpr POpRoot()=default
Operation extensions main header.
constexpr decltype(auto) indexOp(const Sptr< IndexT > &i)
constexpr decltype(auto) poproot(const Sptr< IndexT > &ind, const SizeT *parts, Op &&op)
uint64_t SizeT
Definition types.h:38
constexpr decltype(auto) coproot(const CArrayBase< T > &a, const Sptr< IndexT > &ind)
std::vector< T, Allocator< T > > Vector
Definition types.h:310
constexpr decltype(auto) contraction(F &&f, Op &&op, const Sptr< IndexT > &i)
Sptr< Range > rangeCast(const RangePtr r)
decltype(auto) vreg(const T *d, const EPosT &pos)
Definition reg.cc.h:29
constexpr decltype(auto) operation(F &&f, const Ops &... ops)
constexpr decltype(auto) assignxpr(const Tar &tar, const Src &src)
std::shared_ptr< T > Sptr
Definition types.h:48
auto pos_unpack_args(const F &f, const PosT &pos, const Tuple< Ops... > &args)
constexpr decltype(auto) oproot(ArrayBase< T > &a, const Sptr< IndexT > &ind)
Operation types declarations.
Operation utilities declarations.