#ifndef __cxz_access_h__ #define __cxz_access_h__ namespace CNORXZ { namespace { using namespace CNORXZInternal; } template <class T> struct VType { typedef T type; static constexpr size_t MULT = sizeof(type)/sizeof(T); }; template <> struct VType<double> { typedef v256 type; static constexpr size_t MULT = sizeof(type)/sizeof(double); }; template <template <typename...> class F,typename... Ts> inline auto mkVFuncPtr(const std::shared_ptr<F<Ts...>>& f) { return std::shared_ptr<F<typename VType<Ts>::type...>>(); // empty, implement corresponding constructors...!!! } template <template <typename...> class F,typename... Ts> inline auto mkVFunc(const F<Ts...>& f) { return F<typename VType<Ts>::type...>(); // empty, implement corresponding constructors...!!! } template <class F> using VFunc = decltype(mkVFunc(std::declval<F>())); //template <class F> //using VFunc = F; template <typename T, class F, class... Indices> class OpAccess { private: std::tuple<std::shared_ptr<Indices>...> mInds; public: static constexpr bool ISSTATIC = false; template <typename Op, class ExtType> inline void operator()(T*& t, size_t pos, const Op& op, ExtType e) { F::selfApply(t[pos](mInds), op.get(e)); // s.th. like that // TODO for classes related to the r.h.s.: // forward get(e) to elements returned by get(e) until basic types are reached // (also same for rootSteps etc...) !!!! // introduce traits !!!! // !!!! } }; // static polymorphism template <class AccessClass> class AccessTemplate { public: typedef AccessClass AC; AccessTemplate(const AccessTemplate& in) = default; AccessTemplate(AccessTemplate&& in) = default; AccessTemplate& operator=(const AccessTemplate& in) = default; AccessTemplate& operator=(AccessTemplate&& in) = default; AccessClass& THIS() { return static_cast<AccessClass&>(*this); } const AccessClass& THIS() const { return static_cast<const AccessClass&>(*this); } inline auto get(size_t pos); inline auto get(size_t pos) const; inline auto oget(size_t pos) const; template <class F, typename Op, class ExtType> inline void exec(size_t pos, const Op& op, ExtType e) const; protected: AccessTemplate() = default; }; template <typename T> class PointerAccess : public AccessTemplate<PointerAccess<T>> { public: typedef T value_type; typedef T in_type; static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type); friend class AccessTemplate<PointerAccess<T>>; private: PointerAccess() = default; T* mPtr = nullptr; T* mOrigPtr = nullptr; public: PointerAccess(T* ptr, T* origPtr) : mPtr(ptr), mOrigPtr(origPtr) {} PointerAccess(const PointerAccess& in) = default; PointerAccess(PointerAccess&& in) = default; PointerAccess& operator=(const PointerAccess& in) = default; PointerAccess& operator=(PointerAccess&& in) = default; T* get(size_t pos) { return mPtr+pos; } T* get(size_t pos) const { return mPtr+pos; } PointerAccess<T>& set(size_t pos) { mPtr = mOrigPtr + pos; return *this; } T* oget(size_t pos) const { return mOrigPtr+pos; } template <class F, typename Op, class ExtType> inline void exec(size_t pos, const Op& op, ExtType e) const { F::selfApply(*get(pos),op.get(e)); } }; template <typename T> class VPointerAccess : public AccessTemplate<VPointerAccess<T>> { public: typedef typename VType<T>::type value_type; typedef T in_type; static constexpr size_t VSIZE = sizeof(value_type) / sizeof(in_type); friend class AccessTemplate<VPointerAccess<T>>; private: VPointerAccess() = default; T* mPtr = nullptr; T* mOrigPtr = nullptr; public: VPointerAccess(T* ptr, T* origPtr) : mPtr(ptr), mOrigPtr(origPtr) {} VPointerAccess(const PointerAccess<T>& in) : mPtr(in.get(0)), mOrigPtr(in.oget(0)) {} VPointerAccess(const VPointerAccess& in) = default; VPointerAccess(VPointerAccess&& in) = default; VPointerAccess& operator=(const VPointerAccess& in) = default; VPointerAccess& operator=(VPointerAccess&& in) = default; value_type* get(size_t pos) { return reinterpret_cast<value_type*>(mPtr+pos); } value_type* get(size_t pos) const { return reinterpret_cast<value_type*>(mPtr+pos); } VPointerAccess<T>& set(size_t pos) { mPtr = mOrigPtr + pos; return *this; } value_type* oget(size_t pos) const { return reinterpret_cast<value_type*>(mOrigPtr+pos); } template <class F, typename Op, class ExtType> inline void exec(size_t pos, const Op& op, ExtType e) const { F::selfApply(*get(pos),op.template vget<value_type>(e)); } }; } // namespace CNORXZ #endif