CNORXZ
Container with Native Operation Routines and Expressions
Loading...
Searching...
No Matches
urange.cc.h
Go to the documentation of this file.
1// -*- C++ -*-
12#ifndef __cxz_urange_cc_h__
13#define __cxz_urange_cc_h__
14
15#include <functional>
16#include <algorithm>
17
18#include "urange.h"
19#include "prange.h"
20#include "index_mul.h"
21#include "xpr/for.h"
22#include "operation/op_types.h"
24
25namespace CNORXZ
26{
27 /*===============+
28 | UIndex |
29 +===============*/
30
31 template <typename MetaT>
34 mRangePtr(rangeCast<RangeType>(range)),
35 mMetaPtr(&mRangePtr->get(0))
36 {}
37
38 template <typename MetaT>
40 {
41 IB::mPos = lexpos;
42 return *this;
43 }
44
45 template <typename MetaT>
47 {
48 ++IB::mPos;
49 return *this;
50 }
51
52 template <typename MetaT>
54 {
55 --IB::mPos;
56 return *this;
57 }
58
59 template <typename MetaT>
61 {
62 return UIndex(mRangePtr, IB::mPos + n);
63 }
64
65 template <typename MetaT>
67 {
68 return UIndex(mRangePtr, IB::mPos - n);
69 }
70
71 template <typename MetaT>
73 {
74 return lex() - i.lex();
75 }
76
77 template <typename MetaT>
79 {
80 IB::mPos += n;
81 return *this;
82 }
83
84 template <typename MetaT>
86 {
87 IB::mPos -= n;
88 return *this;
89 }
90
91 template <typename MetaT>
93 {
94 return IB::mPos;
95 }
96
97 template <typename MetaT>
99 {
100 return UPos(mRangePtr->size());
101 }
102
103 template <typename MetaT>
105 {
106 return UPos(mRangePtr->size());
107 }
108
109 template <typename MetaT>
111 {
112 return IndexId<0>(this->ptrId());
113 }
114
115 template <typename MetaT>
117 {
118 return mMetaPtr[IB::mPos];
119 }
120
121 template <typename MetaT>
123 {
124 return toString(this->meta());
125 }
126
127 template <typename MetaT>
129 {
130 return mMetaPtr[IB::mPos];
131 }
132
133 template <typename MetaT>
135 {
136 (*this) = mRangePtr->getMeta(metaPos);
137 return *this;
138 }
139
140 template <typename MetaT>
141 decltype(auto) UIndex<MetaT>::xpr(const Sptr<UIndex<MetaT>>& _this) const
142 {
143 return coproot(mMetaPtr,_this);
144 }
145
146 template <typename MetaT>
148 {
149 CXZ_ASSERT(last >= *this, "got last index position (" << last.lex()
150 << ") smaller than begin index position (" << lex() << ")");
151 const SizeT beginPos = lex();
152 Vector<SizeT> parts(last.lex()-beginPos+1);
153 for(auto i = *this; i != last+1; ++i){
154 parts[i.lex()-beginPos] = i.lex();
155 }
156 return CNORXZ::prange(mRangePtr, parts);
157 }
158
159 template <typename MetaT>
161 {
162 return 1;
163 }
164
165 template <typename MetaT>
167 {
168 return lmax().val();
169 }
170
171 template <typename MetaT>
173 {
174 CXZ_ASSERT(f[0]*s[0] == lmax().val(), "got wrong extension: " << f[0]*s[0]
175 << " vs " << lmax().val());
176 CXZ_ASSERT(CNORXZ::formatIsTrivial(f,s), "format is not trivial: f = " << toString(f)
177 << ", s = " << toString(s));
178 return *this;
179 }
180
181 template <typename MetaT>
182 size_t UIndex<MetaT>::dim() const // = 1
183 {
184 return 1;
185 }
186
187 template <typename MetaT>
189 {
190 return mRangePtr;
191 }
192
193 template <typename MetaT>
194 template <SizeT I>
195 decltype(auto) UIndex<MetaT>::stepSize(const IndexId<I>& id) const
196 {
197 if constexpr(I != 0){
198 return SPos<0>();
199 }
200 else {
201 return UPos(id == this->id() ? 1 : 0);
202 }
203 }
204
205 template <typename MetaT>
206 template <class Xpr, class F>
207 decltype(auto) UIndex<MetaT>::ifor(const Xpr& xpr, F&& f) const
208 {
209 return For<0,Xpr,F>(this->pmax().val(), this->id(), xpr, std::forward<F>(f));
210 }
211
212 template <typename MetaT>
214 {
215 return true;
216 }
217
218 template <typename MetaT, class I1>
219 decltype(auto) operator*(const Sptr<UIndex<MetaT>>& a, const Sptr<I1>& b)
220 {
221 return iptrMul(a, b);
222 }
223
224 /*====================+
225 | URangeFactory |
226 +====================*/
227
228 template <typename MetaT>
230 mSpace(space) {}
231
232 template <typename MetaT>
234 mSpace(space) {}
235
236 template <typename MetaT>
238 mSpace(space), mRef(ref) {}
239
240 template <typename MetaT>
242 mSpace(space), mRef(ref) {}
243
244 template <typename MetaT>
246 {
247 const auto& info = typeid(URange<MetaT>);
248 if(mRef != nullptr) {
249 mProd = this->fromCreated(info, {mRef->id()});
250 }
251 if(mProd == nullptr){
252 RangePtr key = mProd = std::shared_ptr<URange<MetaT>>
253 ( new URange<MetaT>( std::move(mSpace) ) );
254 if(mRef != nullptr) { key = mRef; }
255 this->addToCreated(info, { key->id() }, mProd);
256 }
257 }
258
259 /*=============+
260 | URange |
261 +=============*/
262
263 template <typename MetaT>
264 URange<MetaT>::URange(const Vector<MetaT>& space) :
265 RangeInterface<URange<MetaT>>(),
266 mSpace(space)
267 {
268 std::sort(mSpace.begin(), mSpace.end(), std::less<MetaT>());
269 auto itdupl = std::adjacent_find(mSpace.begin(), mSpace.end());
270 CXZ_ASSERT(itdupl == mSpace.end(), "found duplicate: " << *itdupl);
271 }
272
273 template <typename MetaT>
274 URange<MetaT>::URange(Vector<MetaT>&& space) :
275 RangeInterface<URange<MetaT>>(),
276 mSpace(space)
277 {
278 std::sort(mSpace.begin(), mSpace.end(), std::less<MetaT>());
279 auto itdupl = std::adjacent_find(mSpace.begin(), mSpace.end());
280 CXZ_ASSERT(itdupl == mSpace.end(), "found duplicate: " << toString(*itdupl));
281 }
282
283
284 template <typename MetaT>
286 {
287 return mSpace[pos];
288 }
289
290 template <typename MetaT>
292 {
293 return mSpace.data();
294 }
295
296 template <typename MetaT>
298 {
299 auto b = mSpace.begin();
300 auto e = mSpace.end();
301 auto i = std::lower_bound(b, e, meta, std::less<MetaT>());
302 CXZ_ASSERT(i != e, "element with meta data = " << toString(meta) << " not in range"); // check this first, otherwise the next test may potentially result in a seg fault!
303 CXZ_ASSERT(*i == meta, "element with meta data = " << toString(meta) << " not in range");
304 return i - b;
305 }
306
307 template <typename MetaT>
309 {
310 return mSpace.size();
311 }
312
313 template <typename MetaT>
315 {
316 return 1;
317 }
318
319 template <typename MetaT>
321 {
322 return toString(this->get(pos));
323 }
324
325 template <typename MetaT>
327 {
328 return typeid(URange<MetaT>);
329 }
330
331 template <typename MetaT>
333 {
334 return typeid(MetaT);
335 }
336
337 template <typename MetaT>
339 {
340 auto rx = rangeCast<URange<MetaT>>(r);
341 auto space = mSpace;
342 space.insert(space.end(), rx->mSpace.begin(), rx->mSpace.end());
343 return URangeFactory<MetaT>( space ).create();
344 }
345
346 template <typename MetaT>
348 {
349 return Vector<Uuid> { this->id() };
350 }
351
352 /*=================+
353 | Range Casts |
354 +=================*/
355
356 template <typename MetaT>
358 {
359 template <typename T>
360 static inline Sptr<URange<MetaT>> transform(const RangePtr& r)
361 {
362 if(r->type() == typeid(URange<T>)){
363 auto rr = std::dynamic_pointer_cast<URange<T>>(r);
364 Vector<MetaT> v(rr->size());
365 std::transform(rr->begin(), rr->end(), v.begin(),
366 [](const T& x) { return static_cast<MetaT>(x); } );
367 return std::dynamic_pointer_cast<URange<MetaT>>
368 ( URangeFactory<MetaT>(std::move(v)).create() );
369 }
370 else {
371 return nullptr;
372 }
373 }
374
375 static inline Sptr<URange<MetaT>> cast(const RangePtr& r)
376 {
377 static_assert(std::is_fundamental<MetaT>::value, "got non-fundamental type");
378 CXZ_ASSERT(r->dim() == 1, "range cast into URange<Int>: source range must have dim = 1, got " << r->dim());
379 Sptr<URange<MetaT>> o = nullptr;
380 o = transform<SizeT>(r); if(o) return o;
381 o = transform<Int>(r); if(o) return o;
382 o = transform<LInt>(r); if(o) return o;
383 o = transform<Double>(r); if(o) return o;
384 // else general transform using DType (better than nothing), to be implemented!!!
385 CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
386 return nullptr;
387 }
388 };
389
390 template <typename T> struct is_vector : std::false_type {};
391 template <typename T, typename A> struct is_vector<std::vector<T,A>> : std::true_type {};
392
393 template <typename U>
395 {
396 template <typename T>
397 static inline Sptr<URange<Vector<U>>> transform(const RangePtr& r)
398 {
399 if(r->type() == typeid(URange<T>)){
400 auto rr = std::dynamic_pointer_cast<URange<T>>(r);
401 Vector<Vector<U>> v(rr->size());
402 std::transform(rr->begin(), rr->end(), v.begin(),
403 [](const T& x) { return Vector<U> { static_cast<U>(x) }; } );
404 return std::dynamic_pointer_cast<URange<Vector<U>>>
405 ( URangeFactory<Vector<U>>(std::move(v)).create() );
406 }
407 else {
408 return nullptr;
409 }
410 }
411
412 template <typename T, SizeT N>
413 static inline Sptr<URange<Vector<U>>> atransform(const RangePtr& r)
414 {
415 if(r->type() == typeid(URange<Arr<T,N>>)){
416 auto rr = std::dynamic_pointer_cast<URange<Arr<T,N>>>(r);
417 Vector<Vector<U>> v(rr->size());
418 std::transform(rr->begin(), rr->end(), v.begin(),
419 [](const Arr<T,N>& x) {
420 return iter<0,N>( [&](auto i) { return static_cast<U>(x[i]); },
421 [](const auto&... e) { return Vector<U>{ e... }; });
422 } );
423 return std::dynamic_pointer_cast<URange<Vector<U>>>
424 ( URangeFactory<Vector<U>>(std::move(v)).create() );
425 }
426 else {
427 return nullptr;
428 }
429 }
430
431 static inline Sptr<URange<Vector<U>>> cast(const RangePtr& r)
432 {
433 Sptr<URange<Vector<U>>> o = nullptr;
434 if constexpr(std::is_fundamental<U>::value){
435 o = transform<SizeT>(r); if(o) return o;
436 o = transform<Int>(r); if(o) return o;
437 o = transform<LInt>(r); if(o) return o;
438 o = transform<Double>(r); if(o) return o;
439 o = atransform<SizeT,2>(r); if(o) return o;
440 o = atransform<Int,2>(r); if(o) return o;
441 o = atransform<LInt,2>(r); if(o) return o;
442 o = atransform<Double,2>(r); if(o) return o;
443 o = atransform<SizeT,3>(r); if(o) return o;
444 o = atransform<Int,3>(r); if(o) return o;
445 o = atransform<LInt,3>(r); if(o) return o;
446 o = atransform<Double,3>(r); if(o) return o;
447 }
448 // else general transform using DType (better than nothing), to be implemented!!!
449 CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
450 }
451 };
452
453
454 template <typename MetaT>
455 Sptr<URange<MetaT>> RangeCast<URange<MetaT>>::func(const RangePtr& r)
456 {
457 if constexpr(std::is_fundamental<MetaT>::value or is_vector<MetaT>::value){
458 return URangeCast<MetaT>::cast(r);
459 }
460 else {
461 CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
462 return nullptr;
463 }
464 }
465
466 template <typename MetaT>
468 {
469 return URangeFactory<MetaT>(space).create();
470 }
471
472}
473
474#endif
#define CXZ_ERROR(errmsg)
Definition assert.h:26
#define CXZ_ASSERT(statement, errmsg)
Definition assert.h:40
UIndex & operator++()
Definition urange.cc.h:46
RangePtr prange(const UIndex< MetaType > &last) const
Definition urange.cc.h:147
SizeT lex() const
Definition urange.cc.h:92
UIndex & reformat(const Vector< SizeT > &f, const Vector< SizeT > &s)
Definition urange.cc.h:172
UIndex & operator--()
Definition urange.cc.h:53
UIndex & operator=(SizeT lexpos)
Definition urange.cc.h:39
UIndex operator+(Int n) const
Definition urange.cc.h:60
SizeT deepFormat() const
Definition urange.cc.h:160
UIndex & at(const MetaT &metaPos)
Definition urange.cc.h:134
SizeT deepMax() const
Definition urange.cc.h:166
UIndex & operator+=(Int n)
Definition urange.cc.h:78
UPos pmax() const
Definition urange.cc.h:98
bool formatIsTrivial() const
Definition urange.cc.h:213
Sptr< RangeType > range() const
Definition urange.cc.h:188
SizeT dim() const
Definition urange.cc.h:182
String stringMeta() const
Definition urange.cc.h:122
const MetaT & operator*() const
Definition urange.cc.h:116
UIndex operator-(Int n) const
Definition urange.cc.h:66
UIndex & operator-=(Int n)
Definition urange.cc.h:85
IndexId< 0 > id() const
Definition urange.cc.h:110
UIndex(const RangePtr &range, SizeT pos=0)
Definition urange.cc.h:32
UPos lmax() const
Definition urange.cc.h:104
const MetaT & meta() const
Definition urange.cc.h:128
const MetaType * get() const
Definition urange.cc.h:291
virtual SizeT dim() const override final
Definition urange.cc.h:314
virtual const TypeInfo & type() const override final
Definition urange.cc.h:326
virtual String stringMeta(SizeT pos) const override final
Definition urange.cc.h:320
virtual RangePtr extend(const RangePtr &r) const override final
Definition urange.cc.h:338
SizeT getMeta(const MetaType &metaPos) const
Definition urange.cc.h:297
virtual const TypeInfo & metaType() const override final
Definition urange.cc.h:332
virtual SizeT size() const override final
Definition urange.cc.h:308
For expressions declarations.
Index multiplication.
std::string String
Definition types.h:42
std::type_info TypeInfo
Definition types.h:71
RangePtr urange(const Vector< MetaT > &space)
Definition urange.cc.h:467
uint64_t SizeT
Definition types.h:38
constexpr decltype(auto) coproot(const CArrayBase< T > &a, const Sptr< IndexT > &ind)
Sptr< RangeBase > RangePtr
Definition types.h:157
std::vector< T, Allocator< T > > Vector
Definition types.h:310
int32_t Int
Definition types.h:36
decltype(auto) xpr(const Sptr< I > &i)
Sptr< Range > rangeCast(const RangePtr r)
std::array< T, N > Arr
Definition types.h:45
decltype(auto) iptrMul(const Sptr< I1 > &a, const Sptr< I2 > &b)
bool formatIsTrivial(const Vector< SizeT > &f, const Vector< SizeT > &s)
String toString(const T &a)
RangePtr prange(const Sptr< RangeT > &range, const Vector< SizeT > &parts)
Definition prange.cc.h:401
std::shared_ptr< T > Sptr
Definition types.h:48
Operation types template implementations.
Operation types declarations.
PRange, PRangeFactory and PIndex declaration.
static Sptr< URange< Vector< U > > > transform(const RangePtr &r)
Definition urange.cc.h:397
static Sptr< URange< Vector< U > > > atransform(const RangePtr &r)
Definition urange.cc.h:413
static Sptr< URange< Vector< U > > > cast(const RangePtr &r)
Definition urange.cc.h:431
static Sptr< URange< MetaT > > transform(const RangePtr &r)
Definition urange.cc.h:360
static Sptr< URange< MetaT > > cast(const RangePtr &r)
Definition urange.cc.h:375
URange, URangeFactory and UIndex declaration.