conversions

This commit is contained in:
Christian Zimmermann 2019-02-12 22:34:09 +01:00
parent f339778a59
commit 0326ebc505
2 changed files with 156 additions and 20 deletions

64
src/include/conversions.h Normal file
View file

@ -0,0 +1,64 @@
#ifndef __ma_conversions_h__
#define __ma_conversions_h__
#include "multi_array.h"
#include "slice.h"
namespace MultiArrayTools
{
namespace ConversionSizes
{
template <size_t N>
struct OrigSize
{
template <typename C, typename T>
struct FromTo
{
static void check() { static_assert( not N % (sizeof(T) / sizeof(C)), "conversion does not fit" ); }
static constexpr size_t SIZE = N * sizeof(T) / sizeof(C);
};
};
template <>
struct OrigSize<-1>
{
template <typename C, typename T>
struct FromTo
{
static void check() {}
static constexpr size_t SIZE = -1;
};
};
}
namespace
{
template <typename C, typename T, size_t N>
using SC = ConversionSizes::OrigSize<N>::template FromTo<C,T>;
template <typename C, typename T, class Range>
using SCR = SC<C,T,typename Range::SIZE>;
template <typename C, typename T, class Range>
using SCRR = GenSingleRange<typename Range::value_type,SpaceType::NONE,SCR<C,T,typename Range::SIZE>;
}
template <typename C, typename T, class Range, class... Ranges>
Slice<C,Ranges...,SCRR<C,T,Range>> tcast(MultiArray<T,Ranges...,Range>& ma)
{
return Slice<C,Ranges...,SCRR<C,T,Range>>
( ma.range()->space(), reinterpret_cast<C*>( ma.data() ) );
}
template <typename C, typename T, class Range, class... Ranges>
ConstSlice<C,Ranges...,SCRR<C,T,Range>> tcast(const MultiArray<T,Ranges...,Range>& ma)
{
return ConstSlice<C,Ranges...,SCRR<C,T,Range>>
( ma.range()->space(), reinterpret_cast<const C*>( ma.data() ) );
}
}
#endif

View file

@ -83,6 +83,59 @@ namespace MultiArrayTools
return a; return a;
} }
template <typename T>
std::vector<T>& operator-=(std::vector<T>& a, const std::vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::minus<T>());
return a;
}
template <typename T>
std::vector<T>& operator*=(std::vector<T>& a, const std::vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::multiplies<T>());
return a;
}
template <typename T>
std::vector<T>& operator/=(std::vector<T>& a, const std::vector<T>& b)
{
std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::divides<T>());
return a;
}
template <typename T>
std::vector<T> operator+(std::vector<T>& a, const std::vector<T>& b)
{
std::vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::plus<T>());
return out;
}
template <typename T>
std::vector<T> operator-(std::vector<T>& a, const std::vector<T>& b)
{
std::vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::minus<T>());
return out;
}
template <typename T>
std::vector<T> operator*(std::vector<T>& a, const std::vector<T>& b)
{
std::vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::multiplies<T>());
return out;
}
template <typename T>
std::vector<T> operator/(std::vector<T>& a, const std::vector<T>& b)
{
std::vector<T> out(a.size());
std::transform(a.begin(), a.end(), b.begin(), out.begin(), std::divides<T>());
return out;
}
template <class OperationClass, typename T> template <class OperationClass, typename T>
class OperationTemplate<std::vector<T>,OperationClass> : public OperationBase<std::vector<T>,OperationClass> class OperationTemplate<std::vector<T>,OperationClass> : public OperationBase<std::vector<T>,OperationClass>
{ {
@ -101,29 +154,48 @@ namespace MultiArrayTools
friend OperationClass; friend OperationClass;
}; };
inline std::array<int,2>& operator+=(std::array<int,2>& a, const std::array<int,2>& b) template <typename T, size_t N>
inline std::array<T,N> operator+(std::array<T,N>& a, const std::array<T,N>& b)
{ {
std::get<0>(a) += std::get<0>(b); std::array<T,N> out;
std::get<1>(a) += std::get<1>(b); for(size_t i = 0; i != N; ++i){
return a; out[i] = a[i] + b[i];
}
return out;
} }
inline std::array<int,3>& operator+=(std::array<int,3>& a, const std::array<int,3>& b) template <typename T, size_t N>
inline std::array<T,N> operator-(std::array<T,N>& a, const std::array<T,N>& b)
{ {
std::get<0>(a) += std::get<0>(b); std::array<T,N> out;
std::get<1>(a) += std::get<1>(b); for(size_t i = 0; i != N; ++i){
std::get<2>(a) += std::get<2>(b); out[i] = a[i] - b[i];
return a; }
return out;
} }
inline std::tuple<int,int,int>& operator+=(std::tuple<int,int,int>& a, const std::tuple<int,int,int>& b) template <typename T, size_t N>
inline std::array<T,N> operator*(std::array<T,N>& a, const std::array<T,N>& b)
{ {
std::get<0>(a) += std::get<0>(b); std::array<T,N> out;
std::get<1>(a) += std::get<1>(b); for(size_t i = 0; i != N; ++i){
std::get<2>(a) += std::get<2>(b); out[i] = a[i] * b[i];
return a; }
return out;
} }
template <typename T, size_t N>
inline std::array<T,N> operator/(std::array<T,N>& a, const std::array<T,N>& b)
{
std::array<T,N> out;
for(size_t i = 0; i != N; ++i){
out[i] = a[i] / b[i];
}
return out;
}
} // namespace MultiArrayTools } // namespace MultiArrayTools
#endif #endif