ranges: add some of the possible casts for URange
This commit is contained in:
parent
026c7f1a87
commit
ef45d8cbac
1 changed files with 105 additions and 2 deletions
|
@ -306,12 +306,115 @@ namespace CNORXZ
|
|||
* Range Casts *
|
||||
*******************/
|
||||
|
||||
template <typename MetaType>
|
||||
struct URangeCast
|
||||
{
|
||||
template <typename T>
|
||||
static inline Sptr<URange<MetaType>> transform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(URange<T>)){
|
||||
auto rr = std::dynamic_pointer_cast<URange<T>>(r);
|
||||
Vector<MetaType> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const T& x) { return static_cast<MetaType>(x); } );
|
||||
return std::dynamic_pointer_cast<URange<MetaType>>
|
||||
( URangeFactory<MetaType>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Sptr<URange<MetaType>> cast(const RangePtr& r)
|
||||
{
|
||||
static_assert(std::is_fundamental<MetaType>::value, "got non-fundamental type");
|
||||
CXZ_ASSERT(r->dim() == 1, "range cast into URange<Int>: source range must have dim = 1, got " << r->dim());
|
||||
Sptr<URange<MetaType>> o = nullptr;
|
||||
o = transform<SizeT>(r); if(o) return o;
|
||||
o = transform<Int>(r); if(o) return o;
|
||||
o = transform<LInt>(r); if(o) return o;
|
||||
o = transform<Double>(r); if(o) return o;
|
||||
// else general transform using DType (better than nothing), to be implemented!!!
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct is_vector : std::false_type {};
|
||||
template <typename T, typename A> struct is_vector<std::vector<T,A>> : std::true_type {};
|
||||
|
||||
template <typename U>
|
||||
struct URangeCast<Vector<U>>
|
||||
{
|
||||
template <typename T>
|
||||
static inline Sptr<URange<Vector<U>>> transform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(URange<T>)){
|
||||
auto rr = std::dynamic_pointer_cast<URange<T>>(r);
|
||||
Vector<Vector<U>> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const T& x) { return Vector<U> { static_cast<U>(x) }; } );
|
||||
return std::dynamic_pointer_cast<URange<Vector<U>>>
|
||||
( URangeFactory<Vector<U>>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, SizeT N>
|
||||
static inline Sptr<URange<Vector<U>>> atransform(const RangePtr& r)
|
||||
{
|
||||
if(r->type() == typeid(URange<Arr<T,N>>)){
|
||||
auto rr = std::dynamic_pointer_cast<URange<Arr<T,N>>>(r);
|
||||
Vector<Vector<U>> v(rr->size());
|
||||
std::transform(rr->begin(), rr->end(), v.begin(),
|
||||
[](const Arr<T,N>& x) {
|
||||
return iter<0,N>( [&](auto i) { return static_cast<U>(x[i]); },
|
||||
[](const auto&... e) { return Vector<U>{ e... }; });
|
||||
} );
|
||||
return std::dynamic_pointer_cast<URange<Vector<U>>>
|
||||
( URangeFactory<Vector<U>>(std::move(v)).create() );
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Sptr<URange<Vector<U>>> cast(const RangePtr& r)
|
||||
{
|
||||
Sptr<URange<Vector<U>>> o = nullptr;
|
||||
if constexpr(std::is_fundamental<U>::value){
|
||||
o = transform<SizeT>(r); if(o) return o;
|
||||
o = transform<Int>(r); if(o) return o;
|
||||
o = transform<LInt>(r); if(o) return o;
|
||||
o = transform<Double>(r); if(o) return o;
|
||||
o = atransform<SizeT,2>(r); if(o) return o;
|
||||
o = atransform<Int,2>(r); if(o) return o;
|
||||
o = atransform<LInt,2>(r); if(o) return o;
|
||||
o = atransform<Double,2>(r); if(o) return o;
|
||||
o = atransform<SizeT,3>(r); if(o) return o;
|
||||
o = atransform<Int,3>(r); if(o) return o;
|
||||
o = atransform<LInt,3>(r); if(o) return o;
|
||||
o = atransform<Double,3>(r); if(o) return o;
|
||||
}
|
||||
// else general transform using DType (better than nothing), to be implemented!!!
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MetaType>
|
||||
Sptr<URange<MetaType>> RangeCast<URange<MetaType>>::func(const RangePtr& r)
|
||||
{
|
||||
CXZ_ERROR("to be implemented...");
|
||||
if constexpr(std::is_fundamental<MetaType>::value or is_vector<MetaType>::value){
|
||||
return URangeCast<MetaType>::cast(r);
|
||||
}
|
||||
else {
|
||||
CXZ_ERROR("no range cast available for input range '" << r->type().name() << "'");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue