namespace CNORXZ { template using STP = std::tuple...>; typedef vector > RVEC; template inline bool compareSpaceTypes(const RVEC& rvec) { return RangeHelper::compareSpaceTypes(rvec); } template inline bool setFactory(const RVEC& rvec, std::shared_ptr& fptr) { if(compareSpaceTypes(rvec)) { STP stp; RangeHelper::setSpace(rvec, stp); fptr = std::make_shared >(stp); return true; } else { return false; } } size_t indexId() { static size_t id = 0; ++id; return id; } std::shared_ptr mkMULTI(char const** dp, size_t metaSize) { std::shared_ptr out = nullptr; RVEC rvec(metaSize); for(size_t i = 0; i != metaSize; ++i){ auto ff = createRangeFactory(dp); rvec[i] = ff->create(); } if(metaSize == 0){ assert(0); } else if(metaSize == 1) { #define register_multi1(TT0) if(setFactory(rvec, out)) {} else #include "ranges/multi_range_register.h" #undef register_multi1 assert(0); } else if(metaSize == 2) { #define register_multi2(TT0,TT1) if(setFactory(rvec, out)) {} else #include "ranges/multi_range_register.h" #undef register_multi2 assert(0); } else if(metaSize == 3) { #define register_multi3(TT0,TT1,TT2) if(setFactory(rvec, out)) {} else #include "ranges/multi_range_register.h" #undef register_multi3 assert(0); } else if(metaSize == 4) { #define register_multi4(TT0,TT1,TT2,TT3) if(setFactory(rvec, out)) {} else #include "ranges/multi_range_register.h" #undef register_multi4 assert(0); } else { assert(0); } return out; } std::shared_ptr mkANONYMOUS(char const** dp, size_t metaSize) { std::shared_ptr out = nullptr; auto arf = std::make_shared(); for(size_t i = 0; i != metaSize; ++i){ auto ff = createRangeFactory(dp); arf->append( ff->create() ); } out = arf; return out; } std::shared_ptr mkANY(int metaType, size_t metaSize, char const** dp) { std::shared_ptr out = nullptr; if(metaType == -1){ assert(0); } #define register_type(x) else if(x == metaType) { \ vector::type> vd; \ metaCat(vd, *dp, metaSize); \ out = std::make_shared::type, \ SpaceType::ANY> >(vd); } #include "ranges/type_map.h" #undef register_type else { assert(0); } return out; } std::shared_ptr createSingleRangeFactory(const vector*& d, int metaType, size_t size) { std::shared_ptr out = nullptr; if(metaType == -1){ assert(0); } #define register_type(x) else if(x == metaType) { \ vector::type> vd(size); \ std::transform(d,d+size,vd.begin(), \ [](const vector& c) \ { assert(c.size() == sizeof(TypeMap::type)); \ return *reinterpret_cast::type const*>(c.data()); }); \ out = std::make_shared::type, \ SpaceType::ANY> >(vd); } #include "ranges/type_map.h" #undef register_type else { assert(0); } return out; } std::shared_ptr createRangeFactory(char const** dp) { DataHeader h = *reinterpret_cast(*dp); *dp += sizeof(DataHeader); std::shared_ptr out = nullptr; if(h.multiple != 0){ if(h.spaceType == static_cast( SpaceType::ANY )) { // multi range out = mkMULTI(dp, h.metaSize); } else if(h.spaceType == static_cast( SpaceType::ANON ) ) { // anonymous range out = mkANONYMOUS(dp, h.metaSize); } else { assert(0); } } else { if(h.spaceType == static_cast( SpaceType::ANY ) ) { // generic single range out = mkANY(h.metaType, h.metaSize, dp); } else if(h.spaceType == static_cast( SpaceType::NONE ) ) { // classic range size_t size = *reinterpret_cast(*dp); out = std::make_shared >(size); } #define include_range_type(x,n) else if(h.spaceType == static_cast( SpaceType::x ) ) { \ out = mk##x(*dp, h.metaSize); } #include "ranges/range_types/header.h" #undef inlcude_range_type else { assert(0); } *dp += h.metaSize; } return out; } }