diff --git a/CMakeLists.txt b/CMakeLists.txt index 0887a80..9434d89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -Wpedantic -Wno enable_testing() +set(INSTALL_PATH ${CMAKE_SOURCE_DIR}/install) + find_package( GTest REQUIRED ) if(GTest_FOUND) include_directories(${GTEST_INCLUDE_DIRS}) @@ -20,26 +22,11 @@ else() message(FATAL_ERROR "Threads not found") endif() -include_directories(src) +#include_directories(src) -set(INDEX_CC_FILES "${INDEX_CC_FILES}" "src/ranges/range_base.cc" "src/ranges/index_info.cc") -set(MA_CC_FILES "${MA_CC_FILES}" "${INDEX_CC_FILES}" "src/operation_utils.cc") - -add_executable(iutest src/ranges/tests/index_unit_test.cc ${INDEX_CC_FILES}) -target_link_libraries(iutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_test(NAME iutest COMMAND iutest) - -add_executable(mautest src/tests/ma_unit_test.cc ${MA_CC_FILES}) -target_link_libraries(mautest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_test(NAME mautest COMMAND mautest) - -add_executable(oputest src/tests/op_unit_test.cc ${MA_CC_FILES}) -target_link_libraries(oputest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) -add_test(NAME oputest COMMAND oputest) - -add_executable(opptest src/tests/op_perf_test.cc ${MA_CC_FILES}) -#target_link_libraries(oputest) - -#install(TARGETS testm DESTINATION install) +#set(INDEX_CC_FILES "${INDEX_CC_FILES}" "src/ranges/range_base.cc" "src/ranges/index_info.cc") +#set(MA_CC_FILES "${MA_CC_FILES}" "${INDEX_CC_FILES}" "src/operation_utils.cc") set(CMAKE_INSTALL_PREFIX ..) + +add_subdirectory(src) diff --git a/src/arith.h b/install/include/arith.h similarity index 100% rename from src/arith.h rename to install/include/arith.h diff --git a/src/base_def.h b/install/include/base_def.h similarity index 100% rename from src/base_def.h rename to install/include/base_def.h diff --git a/src/helper_tools.h b/install/include/helper_tools.h similarity index 100% rename from src/helper_tools.h rename to install/include/helper_tools.h diff --git a/src/mbase_def.h b/install/include/mbase_def.h similarity index 100% rename from src/mbase_def.h rename to install/include/mbase_def.h diff --git a/src/multi_array.h b/install/include/multi_array.h similarity index 100% rename from src/multi_array.h rename to install/include/multi_array.h diff --git a/src/multi_array_header.h b/install/include/multi_array_header.h similarity index 100% rename from src/multi_array_header.h rename to install/include/multi_array_header.h diff --git a/src/multi_array_operation.h b/install/include/multi_array_operation.h similarity index 99% rename from src/multi_array_operation.h rename to install/include/multi_array_operation.h index 75c65a9..38bc5f3 100644 --- a/src/multi_array_operation.h +++ b/install/include/multi_array_operation.h @@ -13,7 +13,7 @@ #include "mbase_def.h" //#include "block/block.h" -#include "operation_utils.h" +//#include "operation_utils.h" #include "ranges/rheader.h" #include "pack_num.h" @@ -96,8 +96,7 @@ namespace MultiArrayTools typedef OperationBase OB; typedef ContainerRange CRange; typedef typename MultiRange::IndexType IndexType; - typedef MBlock bType; - + OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, std::shared_ptr& index); @@ -118,7 +117,6 @@ namespace MultiArrayTools T* mDataPtr; std::shared_ptr mIndex; IndexInfo mIInfo; - mutable bType mBlock; }; diff --git a/src/pack_num.h b/install/include/pack_num.h similarity index 61% rename from src/pack_num.h rename to install/include/pack_num.h index d6510eb..9631565 100644 --- a/src/pack_num.h +++ b/install/include/pack_num.h @@ -17,33 +17,6 @@ namespace MultiArrayHelper template struct PackNum { - - template - static void makeBlockTypeVec(std::vector >& btv, - const std::tuple& ops, - std::shared_ptr idxPtr, bool init) - { - auto subvec = std::move( std::get(ops).block(idxPtr, init) ); - btv.insert(btv.end(), subvec.begin(), subvec.end() ); - PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); - } - - template - static void makeBlockTypeVec(std::vector >& btv, - const std::tuple& ops, - const IndexInfo* idxPtr, bool init) - { - auto subvec = std::move( std::get(ops).block(idxPtr, init) ); - btv.insert(btv.end(), subvec.begin(), subvec.end() ); - PackNum::makeBlockTypeVec(btv, ops, idxPtr, init); - } - - template - static void unpackArgs(BlockResult& res, const ArgTuple& tp, const Args&... args) - { - PackNum::template unpackArgs(res, tp, std::get(tp).get(), args...); - } - template static void printTuple(std::ostream& out, const std::tuple& tp) { @@ -88,34 +61,6 @@ namespace MultiArrayHelper template<> struct PackNum<0> { - - template - static void unpackArgs(BlockResult& res, const ArgTuple& tp, const Args&... args) - { - static_assert(sizeof...(Args) == std::tuple_size::value-1, - "inconsistent number of arguments"); - BlockBinaryOp(tp).get()), decltype(args)...> f(res); - f(std::get<0>(tp).get(), args...); - } - - template - static void makeBlockTypeVec(std::vector >& btv, - const std::tuple& ops, - std::shared_ptr idxPtr, bool init) - { - auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); - btv.insert(btv.end(), subvec.begin(), subvec.end() ); - } - - template - static void makeBlockTypeVec(std::vector >& btv, - const std::tuple& ops, - const IndexInfo* idxPtr, bool init) - { - auto subvec = std::move( std::get<0>(ops).block(idxPtr, init) ); - btv.insert(btv.end(), subvec.begin(), subvec.end() ); - } - template static void printTuple(std::ostream& out, const std::tuple& tp) { diff --git a/src/ranges/anonymous_range.h b/install/include/ranges/anonymous_range.h similarity index 100% rename from src/ranges/anonymous_range.h rename to install/include/ranges/anonymous_range.h diff --git a/src/ranges/container_range.h b/install/include/ranges/container_range.h similarity index 100% rename from src/ranges/container_range.h rename to install/include/ranges/container_range.h diff --git a/src/ranges/index_base.h b/install/include/ranges/index_base.h similarity index 100% rename from src/ranges/index_base.h rename to install/include/ranges/index_base.h diff --git a/src/ranges/index_info.h b/install/include/ranges/index_info.h similarity index 100% rename from src/ranges/index_info.h rename to install/include/ranges/index_info.h diff --git a/src/ranges/index_type.h b/install/include/ranges/index_type.h similarity index 100% rename from src/ranges/index_type.h rename to install/include/ranges/index_type.h diff --git a/src/ranges/multi_range.h b/install/include/ranges/multi_range.h similarity index 100% rename from src/ranges/multi_range.h rename to install/include/ranges/multi_range.h diff --git a/src/ranges/range_base.h b/install/include/ranges/range_base.h similarity index 83% rename from src/ranges/range_base.h rename to install/include/ranges/range_base.h index 599c373..a0f38c4 100644 --- a/src/ranges/range_base.h +++ b/install/include/ranges/range_base.h @@ -60,6 +60,11 @@ namespace MultiArrayTools bool operator==(const RangeBase& in) const; bool operator!=(const RangeBase& in) const; + + //virtual bool regular() const = 0; // integer distance (e.g. 2,3,4,...) + //virtual bool linear() const = 0; // 1dim valuable (e.g. 2.45, 3.12, 3.56,...) + //virtual bool multi() const = 0; // mdim + //virtual bool maplike() const = 0; // meta type is ~ MultiArray friend RangeFactoryBase; diff --git a/src/ranges/range_types/header.h b/install/include/ranges/range_types/header.h similarity index 100% rename from src/ranges/range_types/header.h rename to install/include/ranges/range_types/header.h diff --git a/src/ranges/range_types/spin_range.h b/install/include/ranges/range_types/spin_range.h similarity index 100% rename from src/ranges/range_types/spin_range.h rename to install/include/ranges/range_types/spin_range.h diff --git a/src/ranges/rbase_def.h b/install/include/ranges/rbase_def.h similarity index 100% rename from src/ranges/rbase_def.h rename to install/include/ranges/rbase_def.h diff --git a/src/ranges/rheader.h b/install/include/ranges/rheader.h similarity index 100% rename from src/ranges/rheader.h rename to install/include/ranges/rheader.h diff --git a/src/ranges/rpack_num.h b/install/include/ranges/rpack_num.h similarity index 100% rename from src/ranges/rpack_num.h rename to install/include/ranges/rpack_num.h diff --git a/src/ranges/single_range.h b/install/include/ranges/single_range.h similarity index 100% rename from src/ranges/single_range.h rename to install/include/ranges/single_range.h diff --git a/src/ranges/vindex_base.h b/install/include/ranges/vindex_base.h similarity index 100% rename from src/ranges/vindex_base.h rename to install/include/ranges/vindex_base.h diff --git a/src/ranges/vindex_wrapper.h b/install/include/ranges/vindex_wrapper.h similarity index 100% rename from src/ranges/vindex_wrapper.h rename to install/include/ranges/vindex_wrapper.h diff --git a/src/utils.h b/install/include/utils.h similarity index 100% rename from src/utils.h rename to install/include/utils.h diff --git a/src/xfor/exttype.h b/install/include/xfor/exttype.h similarity index 100% rename from src/xfor/exttype.h rename to install/include/xfor/exttype.h diff --git a/src/xfor/for_type.h b/install/include/xfor/for_type.h similarity index 100% rename from src/xfor/for_type.h rename to install/include/xfor/for_type.h diff --git a/src/xfor/for_utils.h b/install/include/xfor/for_utils.h similarity index 100% rename from src/xfor/for_utils.h rename to install/include/xfor/for_utils.h diff --git a/src/xfor/xfor.h b/install/include/xfor/xfor.h similarity index 100% rename from src/xfor/xfor.h rename to install/include/xfor/xfor.h diff --git a/install/lib/libmultiarray.a b/install/lib/libmultiarray.a new file mode 100644 index 0000000..765e03e Binary files /dev/null and b/install/lib/libmultiarray.a differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..272d174 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,6 @@ + +include_directories(${CMAKE_SOURCE_DIR}/src/include) +add_subdirectory(tests) +add_subdirectory(lib) + +install(DIRECTORY include/ DESTINATION ${INSTALL_PATH}/include) diff --git a/src/block/bbase_def.h b/src/block/bbase_def.h deleted file mode 100644 index 667dfe6..0000000 --- a/src/block/bbase_def.h +++ /dev/null @@ -1,45 +0,0 @@ - - -#ifndef __bbase_def_h__ -#define __bbase_def_h__ - -namespace MultiArrayHelper -{ - - template - class BlockBinaryOp; - - - template - class BlockBase; - - - template - class MutableBlockBase; - - - template - class Block; - - - template - class MBlock; - - - template - class BlockResult; - - - enum class BlockType { - INDEF = 0, - BLOCK = 1, - VALUE = 2, - SPLIT = 3, - RESULT = 4, - ARRAY = 5 - }; - - -} // end namespace MultiArrayHelper - -#endif diff --git a/src/block/block.h b/src/block/block.h deleted file mode 100644 index a558e28..0000000 --- a/src/block/block.h +++ /dev/null @@ -1,606 +0,0 @@ -// -*- C++ -*- - -#ifndef __ma_block_h__ -#define __ma_block_h__ - -#include -#include - -#include "base_def.h" -#include "block/bbase_def.h" - -namespace MultiArrayHelper -{ - - // manage vectorization in the future !! - - template - class BlockBinaryOp - { - public: - BlockBinaryOp(BlockResult& mRes); - BlockResult& operator()(const BlockClass1& arg1, const BlockClass2& arg2); - private: - BlockResult& mRes; - }; - - template - class BlockBinaryOpSelf - { - public: - BlockBinaryOpSelf(BlockResult& res); - BlockResult& operator()(const BlockClass& arg); - private: - BlockResult& mRes; - }; - - template - class BlockContraction - { - public: - BlockContraction(T& res); - T& operator()(const BlockClass& arg); - private: - T& mRes; - }; - - // EVERYTHING IN HERE MUST N O T BE VITUAL !! - - template - class BlockBase - { - public: - - const BlockClass& THIS() const { return static_cast(*this); } - BlockClass& THIS() { return static_cast(*this); } - - static BlockType sType() { return BlockClass::sType(); } - - size_t size() const; - bool init() const; - - BlockType type() const { return THIS().type(); } - const T& operator[](size_t pos) const { return THIS()[pos]; } - BlockClass& set(size_t npos) { return THIS().set(npos); } - size_t stepSize() const { return THIS().stepSize(); } - - private: - - friend BlockClass; - friend MutableBlockBase; - - DEFAULT_MEMBERS(BlockBase); - BlockBase(size_t size); - - size_t mSize = 0; - bool mInit = false; - }; - - template - std::ostream& operator<<(std::ostream& out, const Block& block) - { - out << block[0]; - for(size_t i = 1; i != block.size(); ++i){ - out << ", " << block[i]; - } - return out; - } - - template - std::ostream& operator<<(std::ostream& out, const MBlock& block) - { - out << block[0]; - for(size_t i = 1; i != block.size(); ++i){ - out << ", " << block[i]; - } - return out; - } - - template - std::ostream& operator<<(std::ostream& out, const BlockResult& block) - { - out << block[0]; - for(size_t i = 1; i != block.size(); ++i){ - out << ", " << block[i]; - } - return out; - } - - - template - class MutableBlockBase : public BlockBase - { - public: - - typedef BlockBase BB; - - T& operator[](size_t pos) { return BB::THIS()[pos]; } - - private: - - friend BlockClass; - - DEFAULT_MEMBERS(MutableBlockBase); - MutableBlockBase(size_t size); - - }; - - template - class Block : public BlockBase > - { - public: - typedef BlockBase > BB; - - static BlockType sType() { return BlockType::BLOCK; } - - DEFAULT_MEMBERS(Block); - Block(const T* data, size_t begPos, size_t size, size_t stepSize); - - BlockType type() const; - const T& operator[](size_t pos) const; - Block& set(size_t npos); - size_t stepSize() const; - - protected: - const T* mData; - const T* mBegPtr; - size_t mStepSize; - }; - - template - class BlockArray : public BlockBase > - { - - typedef BlockBase > BB; - - static BlockType sType() { return BlockType::ARRAY; } - - DEFAULT_MEMBERS(BlockArray); - - BlockArray(const BlockClass& block, size_t size, size_t stepSize); - - BlockType type() const; - BlockClass& operator[](size_t pos); - BlockArray& set(size_t npos); - size_t stepSize() const; - - protected: - const BlockClass& mBlock; - size_t mStepSize; // total stepSize !! - }; - - - template - class MBlock : public MutableBlockBase > - { - public: - - typedef BlockBase > BB; - - static BlockType sType() { return BlockType::BLOCK; } - - DEFAULT_MEMBERS(MBlock); - MBlock(T* data, size_t begPos, size_t size, size_t stepSize); - - template - MBlock& operator=(const BlockClass& in); - - BlockType type() const; - const T& operator[](size_t pos) const; - T& operator[](size_t pos); - MBlock& set(size_t npos); - size_t stepSize() const; - - protected: - T* mData; - T* mBegPtr; - size_t mStepSize; - }; - - template - class BlockResult : public MutableBlockBase > - { - public: - - typedef BlockBase > BB; - using BB::init; - - static BlockType sType() { return BlockType::RESULT; } - - BlockResult(); - BlockResult(const BlockResult& in); - BlockResult(BlockResult&& in); - BlockResult& operator=(const BlockResult& in); - BlockResult& operator=(BlockResult&& in); - - template - BlockResult(size_t size, const ArgTypes&... args); - - ~BlockResult(); - - template - BlockResult& operator=(const BlockClass& in); - - template - BlockResult& init(size_t size, const Args&... args); - - BlockType type() const; - const T& operator[](size_t pos) const; - T& operator[](size_t i); - BlockResult& set(size_t npos); - size_t stepSize() const; - - protected: - T* mResPtr = nullptr; - T* mBegPtr = nullptr; - }; - -} // end namespace MultiArrayHelper - -/* ========================= * - * --- TEMPLATE CODE --- * - * ========================= */ - -namespace MultiArrayHelper -{ - - /********************* - * BlockBinaryOp * - *********************/ - - template - BlockBinaryOp::BlockBinaryOp(BlockResult& res) : mRes(res) {} - - template - BlockResult& BlockBinaryOp::operator()(const BlockClass1& arg1, - const BlockClass2& arg2) - { - static OpFunc f; - //assert(mRes.init() and arg1.init() and arg2.init()); - //assert(arg1.size() == arg2.size()); - for(size_t i = 0; i != arg1.size(); ++i){ - mRes[i] = f(arg1[i], arg2[i]); - } - return mRes; - } - - template - BlockBinaryOpSelf::BlockBinaryOpSelf(BlockResult& res) : mRes(res) {} - - template - BlockResult& BlockBinaryOpSelf::operator()(const BlockClass& arg) - { - static OpFunc f; - //assert(mRes.init() and arg.init()); - //assert(mRes.size() == arg.size()); - for(size_t i = 0; i != arg.size(); ++i){ - mRes[i] = f(mRes[i], arg[i]); - } - return mRes; - } - - template - BlockContraction::BlockContraction(T& res) : mRes(res) {} - - template - T& BlockContraction::operator()(const BlockClass& arg) - { - static OpFunc f; - - for(size_t i = 0; i != arg.size(); ++i){ - mRes = f(mRes, arg[i]); - } - return mRes; - } - - - /***************** - * BlockBase * - *****************/ - - template - BlockBase::BlockBase(size_t size) : mSize(size), mInit(size != 0) {} - - template - size_t BlockBase::size() const - { - return mSize; - } - - template - bool BlockBase::init() const - { - return mInit; - } - - /************************ - * MutableBlockBase * - ************************/ - - template - MutableBlockBase::MutableBlockBase(size_t size) : BlockBase(size) {} - - - /************* - * Block * - *************/ - - template - Block::Block(const T* data, - size_t begPos, size_t size, size_t stepSize) : - BlockBase(size), - mData(data), - mBegPtr(data + begPos), - mStepSize(stepSize) {} - - template - BlockType Block::type() const - { - return mStepSize == 0 ? BlockType::VALUE : - ( mStepSize == 1 ? BlockType::BLOCK : BlockType::SPLIT ); - } - - template - const T& Block::operator[](size_t i) const - { - - return *(mBegPtr + i * mStepSize); - } - - template - Block& Block::set(size_t npos) - { - mBegPtr = mData + npos; - return *this; - } - - template - size_t Block::stepSize() const - { - return 1; - } - - - /****************** - * BlockArray * - ******************/ - - template - BlockArray::BlockArray(const BlockClass& block, size_t size, size_t stepSize) : - BlockBase >(size), - mBlock(block), mStepSize(stepSize) {} - - template - BlockType BlockArray::type() const - { - return BlockType::ARRAY; - } - - template - BlockClass& BlockArray::operator[](size_t pos) - { - return mBlock.set(mStepSize * pos); - } - - template - BlockArray& BlockArray::set(size_t npos) - { - mBlock.set(npos); - return *this; - } - - template - size_t BlockArray::stepSize() const - { - return mStepSize; - } - - - /************** - * MBlock * - **************/ - - template - MBlock::MBlock(T* data, - size_t begPos, size_t size, size_t stepSize) : - MutableBlockBase(size), - mData(data), - mBegPtr(data + begPos), - mStepSize(stepSize) {} - - template - template - MBlock& MBlock::operator=(const BlockClass& in) - { - for(size_t i = 0; i != BB::mSize; ++i){ - (*this)[i] = in[i]; - } - return *this; - } - - template - BlockType MBlock::type() const - { - return mStepSize == 0 ? BlockType::VALUE : - ( mStepSize == 1 ? BlockType::BLOCK : BlockType::SPLIT ); - } - - template - const T& MBlock::operator[](size_t i) const - { - - return *(mBegPtr + i * mStepSize); - } - - template - T& MBlock::operator[](size_t i) - { - - return *(mBegPtr + i * mStepSize); - } - - template - MBlock& MBlock::set(size_t npos) - { - mBegPtr = mData + npos; - return *this; - } - - template - size_t MBlock::stepSize() const - { - return 1; - } - - /******************* - * BlockResult * - *******************/ - - template - BlockResult::BlockResult() : MutableBlockBase() {} - - template - BlockResult::BlockResult(const BlockResult& in) : MutableBlockBase(in.size()) - { - if(BB::mInit){ - mResPtr = new T[BB::mSize]; - } - for(size_t i = 0; i != BB::mSize; ++i){ - mResPtr[i] = in.mResPtr[i]; - } - mBegPtr = mResPtr; - } - - template - BlockResult::BlockResult(BlockResult&& in) : MutableBlockBase(in.size()) - { - if(BB::mInit){ - mResPtr = in.mResPtr; - mBegPtr = mResPtr; - } - in.mSize = 0; - in.mInit = false; - in.mResPtr = nullptr; - in.mBegPtr = nullptr; - } - - template - BlockResult& BlockResult::operator=(const BlockResult& in) - { - BB::mSize = in.size(); - BB::mInit = BB::mInit and BB::mSize != 0; - if(BB::mInit){ - mResPtr = new T[BB::mSize]; - } - for(size_t i = 0; i != BB::mSize; ++i){ - mResPtr[i] = in.mResPtr[i]; - } - mBegPtr = mResPtr; - return *this; - } - - template - BlockResult& BlockResult::operator=(BlockResult&& in) - { - BB::mSize = in.size(); - BB::mInit = BB::mInit and BB::mSize != 0; - if(BB::mInit){ - mResPtr = in.mResPtr; - mBegPtr = mResPtr; - } - in.mSize = 0; - in.mInit = false; - in.mResPtr = nullptr; - return *this; - } - - template - template - BlockResult::BlockResult(size_t size, const ArgTypes&... args) : - MutableBlockBase(size) - { - if(BB::mInit){ - mResPtr = new T[BB::mSize](args...); - } - for(size_t i = 0; i != BB::mSize; ++i){ - mResPtr[i] = static_cast( 0 ); - } - mBegPtr = mResPtr; - } - - template - BlockResult::~BlockResult() - { - delete[] mResPtr; - mResPtr = nullptr; - mBegPtr = nullptr; - BB::mInit = false; - BB::mSize = 0; - } - - template - template - BlockResult& BlockResult::operator=(const BlockClass& in) - { - assert(BB::mInit); - assert(BB::mSize == in.size()); - for(size_t i = 0; i != BB::mSize; ++i){ - (*this)[i] = in[i]; - } - return *this; - } - - template - BlockType BlockResult::type() const - { - return BlockType::RESULT; - } - - template - const T& BlockResult::operator[](size_t i) const - { - return mBegPtr[i]; - } - - template - T& BlockResult::operator[](size_t i) - { - return mBegPtr[i]; - } - - template - BlockResult& BlockResult::set(size_t npos) - { - mBegPtr = mResPtr + npos; - return *this; - } - - template - size_t BlockResult::stepSize() const - { - return 1; - } - - template - template - BlockResult& BlockResult::init(size_t size, const Args&... args) - { - BB::mSize = size; - delete[] mResPtr; - if(BB::mSize != 0){ - BB::mInit = true; - mResPtr = new T[BB::mSize](args...); - } - else { - BB::mInit = false; - } - for(size_t i = 0; i != BB::mSize; ++i){ - mResPtr[i] = static_cast( 0 ); - } - mBegPtr = mResPtr; - return *this; - } - -} // end namespace MultiArrayHelper - -#endif diff --git a/src/include/arith.h b/src/include/arith.h new file mode 100644 index 0000000..540c071 --- /dev/null +++ b/src/include/arith.h @@ -0,0 +1,46 @@ + +#ifndef __arith_h__ +#define __arith_h__ + +namespace MultiArrayHelper +{ + // OPERATIONS (STATIC) + template + struct plus + { + static inline T apply(T a1, T a2) + { + return a1 + a2; + } + }; + + template + struct minus + { + static inline T apply(T a1, T a2) + { + return a1 - a2; + } + }; + + template + struct multiplies + { + static inline T apply(T a1, T a2) + { + return a1 * a2; + } + }; + + template + struct divides + { + static inline T apply(T a1, T a2) + { + return a1 / a2; + } + }; + +} // end namespace MultiArrayHelper + +#endif diff --git a/src/include/base_def.h b/src/include/base_def.h new file mode 100644 index 0000000..10f833b --- /dev/null +++ b/src/include/base_def.h @@ -0,0 +1,35 @@ +// -*- C++ -*- + +#ifndef __base_def_h__ +#define __base_def_h__ + +#include + +#define DEBUG_MODE_X + +#ifdef DEBUG_MODE_X + +#include +#define CHECK std::cout << __FILE__ << ": @" << __LINE__ << " in " << __func__ << std::endl; +#define VCHECK(a) std::cout << __FILE__ << ": @" << __LINE__ \ + << " in " << __func__ << ": " << #a << " = " << a << std::endl; + +#else +#define CHECK +#define VCHECK(a) + +#endif + +#define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \ + __class_name__(const __class_name__& in) = default; \ + __class_name__& operator=(const __class_name__& in) = default; \ + __class_name__(__class_name__&& in) = default; \ + __class_name__& operator=(__class_name__&& in) = default + +#define DEFAULT_MEMBERS_X(__class_name__) __class_name__(const __class_name__& in) = default; \ + __class_name__& operator=(const __class_name__& in) = default; \ + __class_name__(__class_name__&& in) = default; \ + __class_name__& operator=(__class_name__&& in) = default + + +#endif diff --git a/src/include/helper_tools.h b/src/include/helper_tools.h new file mode 100644 index 0000000..8f53e4e --- /dev/null +++ b/src/include/helper_tools.h @@ -0,0 +1,72 @@ + +#ifndef __helper_tools_h__ +#define __helper_tools_h__ + +#include "base_def.h" + +namespace MultiArrayTools +{ + + template + auto getIndex(std::shared_ptr range) + -> std::shared_ptr; + + // only if 'RangeType' is defaultable and unique (Singleton) + template + auto getIndex() -> std::shared_ptr; + + template + auto mkMulti(std::shared_ptr... ranges) + -> std::shared_ptr >; + + template + auto mkMIndex(std::shared_ptr... indices) + -> decltype( getIndex( mkMulti( indices.range()... ) ) ); + + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + template + auto getIndex(std::shared_ptr range) + -> std::shared_ptr + { + return std::dynamic_pointer_cast > + ( range->index() )->get(); + } + + template + auto getIndex() -> std::shared_ptr + { + static_assert( RangeType::defaultable, + /*typeid(typename RangeType).name() + */" is not defaultable" ); + static auto f = RangeType::factory(); + static auto r = std::dynamic_pointer_cast( f.create() ); + return std::dynamic_pointer_cast > + ( r->index() )->get(); + } + + template + auto mkMulti(std::shared_ptr... ranges) + -> std::shared_ptr > + { + MultiRangeFactory mrf( ranges... ); + return std::dynamic_pointer_cast >( mrf.create() ); + } + + template + auto mkMIndex(std::shared_ptr... indices) + -> decltype( getIndex( mkMulti( indices->range()... ) ) ) + { + auto mi = getIndex( mkMulti( indices->range()... ) ); + (*mi)( indices... ); + return mi; + } +} + +#endif diff --git a/src/include/mbase_def.h b/src/include/mbase_def.h new file mode 100644 index 0000000..f3fb0bb --- /dev/null +++ b/src/include/mbase_def.h @@ -0,0 +1,56 @@ + +#ifndef __mbase_def_h__ +#define __mbase_def_h__ + +namespace MultiArrayTools +{ + /*********************** + * Provided Types * + ***********************/ + + // multi_array.h + template + class MultiArrayBase; + + // multi_array.h + template + class MutableMultiArrayBase; + + // multi_array.h + template + class MultiArray; + + // multi_array_operation.h + template + class OperationBase; + + // multi_array_operation.h + template + class MutableOperationBase; + + // multi_array_operation.h + template + class OperationTemplate; + + // multi_array_operation.h + template + class OperationMaster; + + // multi_array_operation.h + template + class OperationRoot; + + // multi_array_operation.h + template + class ConstOperationRoot; + + // multi_array_operation.h + template + class Operation; + + // multi_array_operation.h + template + class Contraction; +} + +#endif diff --git a/src/include/multi_array.h b/src/include/multi_array.h new file mode 100644 index 0000000..7a2fbcf --- /dev/null +++ b/src/include/multi_array.h @@ -0,0 +1,872 @@ +// -*- C++ -*- + +#ifndef __multi_array_h__ +#define __multi_array_h__ + +#include +#include +#include +#include +#include + +#include "base_def.h" +#include "mbase_def.h" + +#include "ranges/rheader.h" + +namespace MultiArrayTools +{ + + // Explicitely specify subranges in template argument !!! + template + class MultiArrayBase + { + public: + + typedef T value_type; + typedef ContainerRange CRange; + typedef typename CRange::IndexType IndexType; + + class const_iterator : public std::iterator + { + public: + + DEFAULT_MEMBERS(const_iterator); + + const_iterator(const MultiArrayBase& ma); + const_iterator(const MultiArrayBase& ma, const typename CRange::IndexType& index); + + // Requirements: + bool operator==(const const_iterator& it) const; + bool operator!=(const const_iterator& it) const; + + const T& operator*() const; + T const* operator->() const; + + const_iterator& operator++(); + const_iterator operator++(int); + const_iterator& operator--(); + const_iterator operator--(int); + + const_iterator& operator+=(int diff); + const_iterator& operator-=(int diff); + const_iterator operator+(int num) const; + const_iterator operator-(int num) const; + + int operator-(const const_iterator& it) const; + + const T& operator[](int num) const; + + bool operator<(const const_iterator& it) const; + bool operator>(const const_iterator& it) const; + bool operator<=(const const_iterator& it) const; + bool operator>=(const const_iterator& it) const; + + // Multi Array specific: + typename ContainerRange::IndexType index() const; + + protected: + MultiArrayBase const* mMAPtr = nullptr; + size_t mPos; + }; + + DEFAULT_MEMBERS(MultiArrayBase); + MultiArrayBase(const std::shared_ptr&... ranges); + + virtual ~MultiArrayBase() = default; + + virtual const T& operator[](const IndexType& i) const = 0; + //virtual const T& operator[](const typename CRange::IndexType& i) const = 0; + virtual const T& at(const typename CRange::IndexType::MetaType& meta) const = 0; + + virtual const T* data() const = 0; + virtual const std::vector& datav() const = 0; + + virtual size_t size() const; + virtual bool isSlice() const = 0; + + virtual const_iterator begin() const; + virtual const_iterator end() const; + + virtual IndexType beginIndex() const; + virtual IndexType endIndex() const; + + virtual const std::shared_ptr& range() const; + + virtual bool isConst() const; + + virtual ConstOperationRoot + operator()(std::shared_ptr&... inds) const; + + virtual bool isInit() const; + + protected: + bool mInit = false; + std::shared_ptr mRange; + + }; + + template + class MutableMultiArrayBase : public MultiArrayBase + { + public: + + typedef ContainerRange CRange; + typedef typename MultiArrayBase::const_iterator const_iterator; + typedef MultiArrayBase MAB; + typedef typename CRange::IndexType IndexType; + + class iterator : public std::iterator, + public std::iterator + { + public: + + DEFAULT_MEMBERS(iterator); + + iterator(MutableMultiArrayBase& ma); + iterator(MutableMultiArrayBase& ma, const IndexType& index); + + // Requirements: + bool operator==(const iterator& it) const; + bool operator!=(const iterator& it) const; + + const T& operator*() const; + T const* operator->() const; + T& operator*(); + T* operator->(); + + iterator& operator++(); + iterator operator++(int); + iterator& operator--(); + iterator operator--(int); + + iterator& operator+=(int diff); + iterator& operator-=(int diff); + iterator operator+(int num) const; + iterator operator-(int num) const; + + int operator-(const iterator& it) const; + + const T& operator[](int num) const; + T& operator[](int num); + + bool operator<(const iterator& it) const; + bool operator>(const iterator& it) const; + bool operator<=(const iterator& it) const; + bool operator>=(const iterator& it) const; + + // Multi Array specific: + typename CRange::IndexType index() const; + + protected: + MutableMultiArrayBase* mMAPtr = nullptr; + size_t mPos; + }; + + using MultiArrayBase::operator[]; + using MultiArrayBase::at; + using MultiArrayBase::data; + using MultiArrayBase::datav; + using MultiArrayBase::begin; + using MultiArrayBase::end; + + DEFAULT_MEMBERS(MutableMultiArrayBase); + MutableMultiArrayBase(const std::shared_ptr&... ranges); + + virtual T& operator[](const IndexType& i) = 0; + virtual T& at(const typename CRange::IndexType::MetaType& meta) = 0; + + virtual T* data() = 0; + virtual std::vector& datav() = 0; + + virtual iterator begin(); + virtual iterator end(); + + virtual bool isConst() const override; + + virtual ConstOperationRoot + operator()(std::shared_ptr&... inds) const override; + virtual OperationRoot operator()(std::shared_ptr&... inds); + }; + + template + class MultiArray : public MutableMultiArrayBase + { + public: + + typedef ContainerRange CRange; + typedef MultiArrayBase MAB; + typedef typename MultiArrayBase::const_iterator const_iterator; + typedef typename MutableMultiArrayBase::iterator iterator; + typedef typename CRange::IndexType IndexType; + + DEFAULT_MEMBERS(MultiArray); + MultiArray(const std::shared_ptr&... ranges); + MultiArray(const std::shared_ptr&... ranges, const std::vector& vec); + MultiArray(const std::shared_ptr&... ranges, std::vector&& vec); + + // Only if ALL ranges have default extensions: + //MultiArray(const std::vector& vec); + //MultiArray(std::vector&& vec); + + // template + // MultiArray(const MultiArray,Range3> in); + + // implement contstructor using FunctionalMultiArray as Input !!! + + //template + //MultiArray& operator=(const MultiArray,Range3> in); + + virtual T& operator[](const IndexType& i) override; + virtual const T& operator[](const IndexType& i) const override; + virtual T& at(const typename CRange::IndexType::MetaType& meta) override; + virtual const T& at(const typename CRange::IndexType::MetaType& meta) const override; + + virtual bool isConst() const override; + virtual bool isSlice() const override; + + template + MultiArray format(const std::shared_ptr&... nrs); // reformat array using 'nr' which in + // total must have the same size as mRange + + virtual const T* data() const override; + virtual T* data() override; + + virtual const std::vector& datav() const override; + virtual std::vector& datav() override; + + // virtual void manipulate(ManipulatorBase& mb, + // const typename CRange::IndexType& manBegin, + // const typename CRange::IndexType& manEnd); + + template + friend class MultiArray; + + private: + std::vector mCont; + }; + + template + class FunctionalMultiArray : public MultiArrayBase + { + public: + + typedef ContainerRange CRange; + typedef MultiArrayBase MAB; + typedef typename MultiArrayBase::const_iterator const_iterator; + typedef typename CRange::IndexType IndexType; + + DEFAULT_MEMBERS(FunctionalMultiArray); + //FunctionalMultiArray(const CRange& range); + FunctionalMultiArray(const std::shared_ptr&... ranges, const Function& func); + + virtual const T& operator[](const IndexType& i) const override; + + virtual bool isConst() const override; + virtual bool isSlice() const override; + + protected: + mutable T mVal; + Function mFunc; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + /************************************** + * MultiArrayBase::const_iterator * + **************************************/ + + template + MultiArrayBase::const_iterator::const_iterator(const MultiArrayBase& ma): + mMAPtr(&ma), mPos(0) { } + + template + MultiArrayBase::const_iterator::const_iterator(const MultiArrayBase& ma, + const typename CRange::IndexType& index): + mMAPtr(&ma), mPos(index.pos()) { } + + template + bool MultiArrayBase::const_iterator::operator==(const const_iterator& it) const + { + return mMAPtr == it.mMAPtr and mPos == it.mPos; + } + + template + bool MultiArrayBase::const_iterator::operator!=(const const_iterator& it) const + { + return mMAPtr != it.mMAPtr or mPos != it.mPos; + } + + template + const T& MultiArrayBase::const_iterator::operator*() const + { + return mMAPtr->data()[mPos]; + } + + template + T const* MultiArrayBase::const_iterator::operator->() const + { + return &mMAPtr->data()[mPos]; + } + + template + typename MultiArrayBase::const_iterator& MultiArrayBase::const_iterator::operator++() + { + ++mPos; + return *this; + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::const_iterator::operator++(int) + { + const_iterator tmp(*this); + ++mPos; + return tmp; + } + + template + typename MultiArrayBase::const_iterator& MultiArrayBase::const_iterator::operator--() + { + --mPos; + return *this; + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::const_iterator::operator--(int) + { + const_iterator tmp(*this); + --mPos; + return tmp; + } + + template + typename MultiArrayBase::const_iterator& MultiArrayBase::const_iterator::operator+=(int diff) + { + mPos += diff; + return *this; + } + + template + typename MultiArrayBase::const_iterator& MultiArrayBase::const_iterator::operator-=(int diff) + { + mPos -= diff; + return *this; + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::const_iterator::operator+(int num) const + { + const_iterator tmp(*this); + tmp += num; + return tmp; + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::const_iterator::operator-(int num) const + { + const_iterator tmp(*this); + tmp -= num; + } + + template + int MultiArrayBase::const_iterator::operator-(const const_iterator& it) const + { + return mPos - it.mPos; + } + + template + const T& MultiArrayBase::const_iterator::operator[](int num) const + { + return *(operator+(num)); + } + + template + bool MultiArrayBase::const_iterator::operator<(const const_iterator& it) const + { + return mPos < it.mPos; + } + + template + bool MultiArrayBase::const_iterator::operator>(const const_iterator& it) const + { + return mPos > it.mPos; + } + + template + bool MultiArrayBase::const_iterator::operator<=(const const_iterator& it) const + { + return mPos <= it.mPos; + } + + template + bool MultiArrayBase::const_iterator::operator>=(const const_iterator& it) const + { + return mPos >= it.mPos; + } + + template + typename MultiArrayBase::IndexType + MultiArrayBase::const_iterator::index() const + { + auto i = mMAPtr->beginIndex(); + i = mPos; + return i; + } + + /********************** + * MultiArrayBase * + **********************/ + + template + MultiArrayBase::MultiArrayBase(const std::shared_ptr&... ranges) + { + ContainerRangeFactory crf(ranges...); + mRange = std::dynamic_pointer_cast >( crf.create() ); + } + + template + size_t MultiArrayBase::size() const + { + return mRange->size(); + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::begin() const + { + return const_iterator(*this, beginIndex()); + } + + template + typename MultiArrayBase::const_iterator MultiArrayBase::end() const + { + return const_iterator(*this, endIndex()); + } + + template + typename MultiArrayBase::IndexType + MultiArrayBase::beginIndex() const + { + return mRange->begin(); + } + + template + typename MultiArrayBase::IndexType + MultiArrayBase::endIndex() const + { + return mRange->end(); + } + + template + const std::shared_ptr::CRange>& + MultiArrayBase::range() const + { + return mRange; + } + + template + bool MultiArrayBase::isConst() const + { + return true; + } + + template + ConstOperationRoot + MultiArrayBase::operator()(std::shared_ptr&... inds) const + { + return ConstOperationRoot(*this, inds...); + } + + template + bool MultiArrayBase::isInit() const + { + return mInit; + } + + /**************************************** + * MutableMultiArrayBase::iterator * + ****************************************/ + + template + MutableMultiArrayBase::iterator::iterator(MutableMultiArrayBase& ma): + mMAPtr(&ma), mPos(0) + { } + + template + MutableMultiArrayBase::iterator::iterator(MutableMultiArrayBase& ma, + const typename CRange::IndexType& index): + mMAPtr(&ma), mPos(index.pos()) + { } + + template + bool MutableMultiArrayBase::iterator::operator==(const iterator& it) const + { + return mMAPtr == it.mMAPtr and mPos == it.mPos; + } + + template + bool MutableMultiArrayBase::iterator::operator!=(const iterator& it) const + { + return mMAPtr != it.mMAPtr or mPos != it.mPos; + } + + template + const T& MutableMultiArrayBase::iterator::operator*() const + { + return mMAPtr->data()[mPos]; + } + + template + T const* MutableMultiArrayBase::iterator::operator->() const + { + return &mMAPtr->data()[mPos]; + } + + template + T& MutableMultiArrayBase::iterator::operator*() + { + return mMAPtr->data()[mPos]; + } + + template + T* MutableMultiArrayBase::iterator::operator->() + { + return &mMAPtr->data()[mPos]; + } + + template + typename MutableMultiArrayBase::iterator& MutableMultiArrayBase::iterator::operator++() + { + ++mPos; + return *this; + } + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::iterator::operator++(int) + { + iterator tmp(*this); + ++mPos; + return tmp; + } + + template + typename MutableMultiArrayBase::iterator& MutableMultiArrayBase::iterator::operator--() + { + --mPos; + return *this; + } + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::iterator::operator--(int) + { + iterator tmp(*this); + --mPos; + return tmp; + } + + template + typename MutableMultiArrayBase::iterator& MutableMultiArrayBase::iterator::operator+=(int diff) + { + mPos += diff; + return *this; + } + + template + typename MutableMultiArrayBase::iterator& MutableMultiArrayBase::iterator::operator-=(int diff) + { + mPos -= diff; + return *this; + } + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::iterator::operator+(int num) const + { + iterator tmp(*this); + tmp += num; + return tmp; + } + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::iterator::operator-(int num) const + { + iterator tmp(*this); + tmp -= num; + } + + template + int MutableMultiArrayBase::iterator::operator-(const iterator& it) const + { + return mPos - it.mPos; + } + + template + const T& MutableMultiArrayBase::iterator::operator[](int num) const + { + return *(operator+(num)); + } + + template + T& MutableMultiArrayBase::iterator::operator[](int num) + { + return *(operator+(num)); + } + + template + bool MutableMultiArrayBase::iterator::operator<(const iterator& it) const + { + return mPos < it.mPos; + } + + template + bool MutableMultiArrayBase::iterator::operator>(const iterator& it) const + { + return mPos > it.mPos; + } + + template + bool MutableMultiArrayBase::iterator::operator<=(const iterator& it) const + { + return mPos <= it.mPos; + } + + template + bool MutableMultiArrayBase::iterator::operator>=(const iterator& it) const + { + return mPos >= it.mPos; + } + + template + typename MutableMultiArrayBase::IndexType + MutableMultiArrayBase::iterator::index() const + { + auto i = mMAPtr->beginIndex(); + i = mPos; + return i; + } + + /****************************** + * MutableMultiArrayBase * + ******************************/ + + template + MutableMultiArrayBase::MutableMultiArrayBase(const std::shared_ptr&... ranges) : + MultiArrayBase(ranges...) {} + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::begin() + { + return iterator(*this, MAB::beginIndex()); + } + + template + typename MutableMultiArrayBase::iterator MutableMultiArrayBase::end() + { + return iterator(*this, MAB::endIndex()); + } + + template + bool MutableMultiArrayBase::isConst() const + { + return false; + } + + template + OperationRoot + MutableMultiArrayBase::operator()(std::shared_ptr&... inds) + { + return OperationRoot(*this, inds...); + } + + template + ConstOperationRoot + MutableMultiArrayBase::operator()(std::shared_ptr&... inds) const + { + return ConstOperationRoot(*this, inds...); + } + + + /******************* + * MultiArray * + *******************/ + + template + MultiArray::MultiArray(const std::shared_ptr&... ranges) : + MutableMultiArrayBase(ranges...), + mCont(MAB::mRange->size()) + { + MAB::mInit = true; + } + + template + MultiArray::MultiArray(const std::shared_ptr&... ranges, const std::vector& vec) : + MutableMultiArrayBase(ranges...), + mCont(vec) + { + MAB::mInit = true; + if(mCont.size() > MAB::mRange->size()){ + mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end()); + } + } + + template + MultiArray::MultiArray(const std::shared_ptr&... ranges, std::vector&& vec) : + MutableMultiArrayBase(ranges...), + mCont(vec) + { + MAB::mInit = true; + if(mCont.size() > MAB::mRange->size()){ + mCont.erase(mCont.begin() + MAB::mRange->size(), mCont.end()); + } + } + + /* + template + template + MultiArray::MultiArray(const MultiArray,Range3> in) : + MutableMultiArrayBase(merge(in.range(), in[ in.beginIndex() ].range())) + // assert that Range2 has always same extension + { + MAB::mInit = true; + mCont.clear(); + for(auto i = in.beginIndex(); i != in.endIndex(); ++i){ + mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end()); + } + assert(mCont.size() == MAB::mRange->size()); + } + */ + /* + template + template + MultiArray& MultiArray::operator=(const MultiArray,Range3> in) + { + MAB::mRange.reset(new Range(merge(in.range(), in[ in.beginIndex() ].range()))); + // assert that Range2 has always same extension + mCont.clear(); + for(auto i = in.beginIndex(); i != in.endIndex(); ++i){ + mCont.insert(mCont.end(), in[i].mCont.begin(), in[i].mCont.end()); + } + assert(mCont.size() == MAB::mRange->size()); + return *this; + } */ + + template + T& MultiArray::operator[](const typename CRange::IndexType& i) + { + return mCont[ i.pos() ]; + } + + template + const T& MultiArray::operator[](const typename CRange::IndexType& i) const + { + return mCont[ i.pos() ]; + } + + template + T& MultiArray::at(const typename CRange::IndexType::MetaType& meta) + { + return mCont[ MAB::beginIndex().at(meta).pos() ]; + } + + template + const T& MultiArray::at(const typename CRange::IndexType::MetaType& meta) const + { + return mCont[ MAB::beginIndex().at(meta).pos() ]; + } + + template + bool MultiArray::isConst() const + { + return false; + } + + template + bool MultiArray::isSlice() const + { + return false; + } + + template + template + MultiArray MultiArray::format(const std::shared_ptr&... nrs) + { + return MultiArray( nrs... , std::move(mCont) ); + } + + template + const T* MultiArray::data() const + { + return mCont.data(); + } + + template + T* MultiArray::data() + { + return mCont.data(); + } + + template + const std::vector& MultiArray::datav() const + { + return mCont; + } + + template + std::vector& MultiArray::datav() + { + return mCont; + } + + + /* + template + void MultiArray::manipulate(ManipulatorBase& mb, + const typename Range::IndexType& manBegin, + const typename Range::IndexType& manEnd) + { + mb.setup(mCont, manBegin.pos(), manEnd.pos()); + mb.execute(); + } + */ + + + /**************************** + * FunctionalMultiArray * + ****************************/ + + /* + template + FunctionalMultiArray::FunctionalMultiArray(const Range& range) : + MultiArrayBase(range), mFunc() {} + */ + template + FunctionalMultiArray::FunctionalMultiArray(const std::shared_ptr&... ranges, + const Function& func) : + MultiArrayBase(ranges...), mFunc(func) {} + + template + const T& FunctionalMultiArray::operator[](const typename CRange::IndexType& i) const + { + mVal = mFunc(i); + return mVal; + } + + template + bool FunctionalMultiArray::isConst() const + { + return true; + } + + template + bool FunctionalMultiArray::isSlice() const + { + return false; + } + +} + +#endif diff --git a/src/include/multi_array_header.h b/src/include/multi_array_header.h new file mode 100644 index 0000000..9dd1e2b --- /dev/null +++ b/src/include/multi_array_header.h @@ -0,0 +1,60 @@ +// -*- C++ -*- + +#ifndef __multi_array_header_h__ +#define __multi_array_header_h__ + +#include +//#include "base_def.h" +//#include "range_base.h" +//#include "index_base.h" +//#include "single_range.h" +//#include "multi_range.h" +//#include "container_range.h" +//#include "block.h" +#include "multi_array_operation.h" +#include "multi_array.h" +#include "helper_tools.h" +//#include "slice.h" +//#include "manipulator.h" +//#include "range_transformer.h" +//#include "ma_functional.h" + +namespace MultiArrayTools +{ + + /********************************* + * Some standard definitions * + *********************************/ + /* + // ===== Index Types ===== + + typedef SingleIndex GenericNI; + typedef SingleIndex GenericFI; + typedef SingleIndex LorentzI; + typedef SingleIndex Space1dNI; + typedef SingleIndex Mom1dNI; + typedef SingleIndex EnsI; + typedef SingleIndex, RangeType::MOMENTUM> LinMomI; + typedef SingleIndex, RangeType::MOMENTUM> LinMom4dI; + // ... + + // ===== Range Types ===== + + typedef SingleRange GenericNR; + typedef SingleRange GenericFR; + typedef SingleRange LorentzR; + typedef SingleRange Space1dNR; + typedef SingleRange DistanceNR; + typedef SingleRange Mom1dNR; + typedef SingleRange EnsR; + typedef MultiRange Space3dNR; + typedef MultiRange Mom3dNR; + typedef SingleRange ValErrR; + typedef SingleRange, RangeType::MOMENTUM> LinMomR; + typedef SingleRange, RangeType::MOMENTUM> LinMom4dR; + // ... + */ + +} + +#endif diff --git a/src/include/multi_array_operation.h b/src/include/multi_array_operation.h new file mode 100644 index 0000000..38bc5f3 --- /dev/null +++ b/src/include/multi_array_operation.h @@ -0,0 +1,599 @@ +// -*- C++ -*- + +#ifndef __multi_array_operation_h__ +#define __multi_array_operation_h__ + +#include +#include +#include +#include +#include + +#include "base_def.h" +#include "mbase_def.h" + +//#include "block/block.h" +//#include "operation_utils.h" +#include "ranges/rheader.h" +#include "pack_num.h" + +#include "ranges/index_info.h" +#include "arith.h" + +namespace MultiArrayTools +{ + + namespace + { + using namespace MultiArrayHelper; + } + + template + class OperationTemplate + { + public: + + OperationClass& THIS() { return static_cast(*this); } + const OperationClass& THIS() const { return static_cast(*this); } + + template + auto operator+(const Second& in) const + -> Operation,OperationClass,Second>; + + template + auto operator-(const Second& in) const + -> Operation,OperationClass,Second>; + + template + auto operator*(const Second& in) const + -> Operation,OperationClass,Second>; + + template + auto operator/(const Second& in) const + -> Operation,OperationClass,Second>; + + template + auto c(std::shared_ptr& ind) const + -> Contraction; + + private: + friend OperationClass; + OperationTemplate() = default; + }; + + template + class OperationMaster + { + public: + + class AssignmentExpr + { + private: + AssignmentExpr() = default; + + OperationMaster& mM; + const OpClass& mSec; + + public: + + static constexpr size_t LAYER = 0; + static constexpr size_t SIZE = OpClass::SIZE; + typedef decltype(mSec.rootSteps()) ExtType; + + AssignmentExpr(OperationMaster& m, const OpClass& sec); + + AssignmentExpr(const AssignmentExpr& in) = default; + AssignmentExpr(AssignmentExpr&& in) = default; + + inline void operator()(size_t start = 0) const; + inline void operator()(size_t start, ExtType last) const; + + auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; + + }; + + typedef T value_type; + typedef OperationBase OB; + typedef ContainerRange CRange; + typedef typename MultiRange::IndexType IndexType; + + OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, + std::shared_ptr& index); + + OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, + std::shared_ptr& index, + const IndexInfo* blockIndex); + + inline void set(size_t pos, T val) { mDataPtr[pos] = val; } + inline void add(size_t pos, T val) { mDataPtr[pos] += val; } + inline T get(size_t pos) const; + + private: + + std::shared_ptr mkIndex(std::shared_ptr& index); + void performAssignment(std::intptr_t blockIndexNum); + OpClass const& mSecond; + MutableMultiArrayBase& mArrayRef; + T* mDataPtr; + std::shared_ptr mIndex; + IndexInfo mIInfo; + }; + + + template + class ConstOperationRoot : /*public OperationBase,*/ + public OperationTemplate > + { + public: + + typedef T value_type; + typedef OperationBase OB; + typedef OperationTemplate > OT; + typedef ContainerRange CRange; + typedef typename CRange::IndexType IndexType; + + static constexpr size_t SIZE = 1; + + ConstOperationRoot(const MultiArrayBase& ma, + const std::shared_ptr&... indices); + + template + inline T get(ET pos) const; + + MExt rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype + + template + Expr loop(Expr exp) const; + + private: + + std::shared_ptr + mkIndex(const MultiArrayBase& ma, + const std::shared_ptr&... indices); + + MultiArrayBase const& mArrayRef; + const T* mDataPtr; + std::shared_ptr mIndex; + IndexInfo mIInfo; + }; + + template + class OperationRoot : public OperationTemplate > + { + public: + + typedef T value_type; + typedef OperationBase OB; + typedef OperationTemplate > OT; + typedef ContainerRange CRange; + typedef typename CRange::IndexType IndexType; + + static constexpr size_t SIZE = 1; + + OperationRoot(MutableMultiArrayBase& ma, + const std::shared_ptr&... indices); + + template + OperationMaster operator=(const OpClass& in); + + template + inline T get(ET pos) const; + + MExt rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype + + template + Expr loop(Expr exp) const; + + private: + + std::shared_ptr + mkIndex(const MultiArrayBase& ma, + const std::shared_ptr&... indices); + + MutableMultiArrayBase& mArrayRef; + T* mDataPtr; + std::shared_ptr mIndex; + IndexInfo mIInfo; + }; + + template + size_t sumRootNum() + { + return typename Op::rootNum(); + } + + template + size_t sumRootNum() + { + return typename Op1::rootNum() + sumRootNum(); + } + + template + struct RootSumN + { + template + struct rs + { + static constexpr size_t SIZE = Op1::SIZE + RootSumN::template rs::SIZE; + }; + }; + + template <> + struct RootSumN<0> + { + template + struct rs + { + static constexpr size_t SIZE = Op1::SIZE; + }; + }; + + + template + struct RootSum + { + static constexpr size_t SIZE = RootSumN::template rs::SIZE; + }; + + + template + class Operation : public OperationTemplate > + { + public: + + typedef T value_type; + typedef OperationBase OB; + typedef OperationTemplate > OT; + typedef OpFunction F; + + static constexpr size_t SIZE = RootSum::SIZE; + + private: + std::tuple mOps; + + public: + typedef decltype(PackNum::template mkSteps(0, mOps)) ETuple; + + Operation(const Ops&... ops); + + template + inline T get(ET pos) const; + + auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype + -> decltype(PackNum::mkSteps(iPtrNum, mOps)); + + template + auto loop(Expr exp) const + -> decltype(PackNum::mkLoop( mOps, exp)); + + }; + + template + class Contraction : public OperationTemplate > + { + public: + + typedef T value_type; + typedef OperationTemplate > OT; + + static constexpr size_t SIZE = Op::SIZE; + + private: + + const Op& mOp; + std::shared_ptr mInd; + + public: + typedef decltype(mOp.rootSteps(0)) ETuple; + + Contraction(const Op& op, std::shared_ptr ind); + + template + inline T get(ET pos) const; + + auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype + -> decltype(mOp.rootSteps(iPtrNum)); + + template + auto loop(Expr exp) const -> decltype(mInd->iforh(exp)); + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + namespace + { + using namespace MultiArrayHelper; + } + + /*************************** + * OperationTemplate * + ***************************/ + + template + template + auto OperationTemplate::operator+(const Second& in) const + -> Operation,OperationClass,Second> + { + return Operation,OperationClass,Second>(THIS(), in); + } + + template + template + auto OperationTemplate::operator-(const Second& in) const + -> Operation,OperationClass,Second> + { + return Operation,OperationClass,Second>(THIS(), in); + } + + template + template + auto OperationTemplate::operator*(const Second& in) const + -> Operation,OperationClass,Second> + { + return Operation,OperationClass,Second>(THIS(), in); + } + + template + template + auto OperationTemplate::operator/(const Second& in) const + -> Operation,OperationClass,Second> + { + return Operation,OperationClass,Second>(THIS(), in); + } + + template + template + auto OperationTemplate::c(std::shared_ptr& ind) const + -> Contraction + { + return Contraction(THIS(), ind); + } + + /***************************************** + * OperationMaster::AssignmentExpr * + *****************************************/ + + template + OperationMaster::AssignmentExpr:: + AssignmentExpr(OperationMaster& m, const OpClass& sec) : + mM(m), mSec(sec) {} + + template + inline void OperationMaster::AssignmentExpr:: + operator()(size_t start, ExtType last) const + { + mM.add(start, mSec.template get(last) ); + } + + template + typename OperationMaster::AssignmentExpr::ExtType + OperationMaster::AssignmentExpr:: + rootSteps(std::intptr_t iPtrNum) const + { + return mSec.rootSteps(iPtrNum); + } + + + /************************* + * OperationMaster * + *************************/ + + template + OperationMaster:: + OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, + std::shared_ptr& index) : + mSecond(second), mArrayRef(ma), mDataPtr(mArrayRef.data()), + mIndex(mkIndex(index)), mIInfo(*mIndex) + { + performAssignment(0); + } + + template + OperationMaster:: + OperationMaster(MutableMultiArrayBase& ma, const OpClass& second, + std::shared_ptr& index, + const IndexInfo* blockIndex) : + mSecond(second), mArrayRef(ma), mDataPtr(mArrayRef.data()), + mIndex(mkIndex(index)), mIInfo(*mIndex) + { + performAssignment(0); + } + + template + std::shared_ptr::IndexType> + OperationMaster:: + mkIndex(std::shared_ptr& index) + { + MultiRangeFactory mrf( index->range() ); + std::shared_ptr > mr = + std::dynamic_pointer_cast >( mrf.create() ); + auto i = std::make_shared( mr->begin() ); + (*i) = *index; + return i; + } + + template + void OperationMaster::performAssignment(std::intptr_t blockIndexNum) + { + AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop + const auto loop = mSecond.template loopifor(ae))>( mIndex->ifor(ae) ); + // hidden Loops outside ! -> auto vectorizable + loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions + } + + template + inline T OperationMaster::get(size_t pos) const + { + return mDataPtr[pos]; + } + + + /**************************** + * ConstOperationRoot * + ****************************/ + + template + ConstOperationRoot:: + ConstOperationRoot(const MultiArrayBase& ma, + const std::shared_ptr&... indices) : + mArrayRef(ma), mDataPtr(mArrayRef.data()), + mIndex( mkIndex(ma,indices...) ), mIInfo(*mIndex) + {} + + template + std::shared_ptr::IndexType> + ConstOperationRoot:: + mkIndex(const MultiArrayBase& ma, + const std::shared_ptr&... indices) + { + auto i = std::make_shared( ma.range() ); + (*mIndex)(indices...); + return i; + } + + template + template + inline T ConstOperationRoot::get(ET pos) const + { + return mDataPtr[pos.val()]; + } + + template + MExt ConstOperationRoot::rootSteps(std::intptr_t iPtrNum) const + { + return MExt(getStepSize( mIndex->info(), iPtrNum )); + //return MExt(getStepSize( getRootIndices( mIndex->info() ), iPtrNum )); + } + + + template + template + Expr ConstOperationRoot::loop(Expr exp) const + { + return exp; + } + + /*********************** + * OperationRoot * + ***********************/ + + template + OperationRoot:: + OperationRoot(MutableMultiArrayBase& ma, + const std::shared_ptr&... indices) : + mArrayRef(ma), mDataPtr(mArrayRef.data()), + mIndex( mkIndex( ma, indices... ) ), mIInfo(*mIndex) + {} + + template + std::shared_ptr::IndexType> + OperationRoot:: + mkIndex(const MultiArrayBase& ma, + const std::shared_ptr&... indices) + { + auto i = std::make_shared( ma.range() ); + (*mIndex)(indices...); + return i; + } + + template + template + OperationMaster OperationRoot::operator=(const OpClass& in) + { + return OperationMaster(mArrayRef, in, mIndex); + } + + template + template + inline T OperationRoot::get(ET pos) const + { + return mDataPtr[pos.val()]; + } + + template + MExt OperationRoot::rootSteps(std::intptr_t iPtrNum) const + { + return MExt(getStepSize( mIndex->info(), iPtrNum )); + //return MExt(getStepSize( getRootIndices( mIndex->info() ), iPtrNum )); + } + + template + template + Expr OperationRoot::loop(Expr exp) const + { + return exp; + } + + /******************* + * Operation * + *******************/ + + template + Operation::Operation(const Ops&... ops) : + mOps(ops...) {} + + template + template + inline T Operation::get(ET pos) const + { + typedef std::tuple OpTuple; + return PackNum:: + template mkOpExpr(pos, mOps); + } + + template + auto Operation::rootSteps(std::intptr_t iPtrNum) const + -> decltype(PackNum::mkSteps(iPtrNum, mOps)) + { + return PackNum::mkSteps(iPtrNum, mOps); + } + + template + template + auto Operation::loop(Expr exp) const + -> decltype(PackNum::mkLoop( mOps, exp )) + { + return PackNum::mkLoop( mOps, exp ); + } + + + /********************* + * Contraction * + *********************/ + + template + Contraction::Contraction(const Op& op, std::shared_ptr ind) : + mOp(op), + mInd(ind) {} + + // forward loop !!!! + template + template + inline T Contraction::get(ET pos) const + { + return mOp.template get(pos); + } + + template + auto Contraction::rootSteps(std::intptr_t iPtrNum) const + -> decltype(mOp.rootSteps(iPtrNum)) + { + return mOp.rootSteps(iPtrNum); + } + + template + template + auto Contraction::loop(Expr exp) const -> decltype(mInd->iforh(exp)) + { + return mInd->iforh(exp); + } + +} + +#endif diff --git a/src/include/pack_num.h b/src/include/pack_num.h new file mode 100644 index 0000000..9631565 --- /dev/null +++ b/src/include/pack_num.h @@ -0,0 +1,108 @@ +// -*- C++ -*- + +#ifndef __pack_num_h__ +#define __pack_num_h__ + +#include +//#include +#include +#include + +#include "base_def.h" +#include "xfor/exttype.h" + +namespace MultiArrayHelper +{ + + template + struct PackNum + { + template + static void printTuple(std::ostream& out, const std::tuple& tp) + { + out << std::get(tp) << ", "; + PackNum::printTuple(out, tp); + } + + template + static auto mkSteps(std::intptr_t ii, const std::tuple& otp) + -> decltype(PackNum::mkSteps(ii, otp).extend( std::get(otp).rootSteps(ii)) ) + { + return PackNum::mkSteps(ii, otp).extend( std::get(otp).rootSteps(ii)); + } + + template + static void mkExt(std::array& out, + const std::array& siar, + const OpClass& second) + { + std::get(out) = second.rootSteps( std::get(siar) ); + PackNum::mkExt(out, siar, second); + } + + template + static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops, const Args&... args) + { + typedef typename std::remove_reference(ops))>::type NextOpType; + static_assert(LAST > NextOpType::SIZE, "inconsistent array positions"); + static constexpr size_t NEXT = LAST - NextOpType::SIZE; + return PackNum::template mkOpExpr + ( pos, ops, std::get(ops).get(Getter::template getX( pos )), args...); + } + + template + static auto mkLoop( const OpTuple& ot, Expr&& exp ) + -> decltype(std::get(ot).loop( PackNum::mkLoop(ot,exp) )) + { + return std::get(ot).loop( PackNum::mkLoop(ot,exp) ); + } + }; + + template<> + struct PackNum<0> + { + template + static void printTuple(std::ostream& out, const std::tuple& tp) + { + out << std::get(tp); + } + + template + static auto mkSteps(std::intptr_t ii, const std::tuple& otp) + -> decltype(std::get<0>(otp).rootSteps(ii)) + { + return std::get<0>(otp).rootSteps(ii); + } + + template + static void mkExt(std::array& out, + const std::array& siar, + const OpClass& second) + { + std::get<0>(out) = second.rootSteps( std::get<0>(siar) ); + } + + template + static inline T mkOpExpr(const ETuple& pos, const OpTuple& ops, const Args&... args) + { + typedef typename std::remove_reference(ops))>::type NextOpType; + static constexpr size_t NEXT = LAST - NextOpType::SIZE; + static_assert(NEXT == 0, "inconsistent array positions"); + return OpFunction::apply(std::get<0>(ops).get(Getter<0>::template getX( pos )), args...); + } + + template + static auto mkLoop( const OpTuple& ot, Expr&& exp ) + -> decltype(std::get<0>(ot).loop( exp )) + { + return std::get<0>(ot).loop( exp ); + } + + + }; + + + +} // end namespace MultiArrayHelper + +#endif diff --git a/src/include/ranges/anonymous_range.h b/src/include/ranges/anonymous_range.h new file mode 100644 index 0000000..110a369 --- /dev/null +++ b/src/include/ranges/anonymous_range.h @@ -0,0 +1,168 @@ +// -*- C++ -*- + +#ifndef __anonymous_range_h__ +#define __anonymous_range_h__ + +#include +//#include "base_def.h" +#include "ranges/range_base.h" +#include "ranges/single_range.h" + +namespace MultiArrayTools +{ + + typedef SingleIndex AnonymousIndex; + + class AnonymousRangeFactory : public RangeFactoryBase + { + public: + + typedef AnonymousRange oType; + + AnonymousRangeFactory() = delete; + + template + AnonymousRangeFactory(const std::tuple...>& origs); + + template + AnonymousRangeFactory(std::shared_ptr... origs); + + std::shared_ptr create(); + + }; + + class AnonymousRange : public RangeInterface + { + typedef RangeBase RB; + typedef typename RangeInterface::IndexType IndexType; + + virtual size_t size() const override; + virtual size_t dim() const override; + + size_t get(size_t pos) const; + size_t getMeta(size_t metaPos) const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + virtual std::shared_ptr index() const override; + + friend AnonymousRangeFactory; + + protected: + + AnonymousRange() = delete; + AnonymousRange(const AnonymousRange& in) = delete; + + template + AnonymousRange(const std::tuple...>& origs); + + template + AnonymousRange(std::shared_ptr... origs); + + size_t mSize; + + std::vector > mOrig; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + /*********************** + * AnonymousRange * + ***********************/ + + template + AnonymousRangeFactory::AnonymousRangeFactory(const std::tuple...>& origs) + { + mProd = std::shared_ptr( new AnonymousRange( origs ) ); + } + + template + AnonymousRangeFactory::AnonymousRangeFactory(std::shared_ptr... origs) + { + mProd = std::shared_ptr( new AnonymousRange( origs... ) ); + } + + std::shared_ptr AnonymousRangeFactory::create() + { + setSelf(); + return mProd; + } + + /*********************** + * AnonymousRange * + ***********************/ + + template + AnonymousRange::AnonymousRange(const std::tuple...>& origs) : + RangeInterface() + { + mOrig.resize(sizeof...(RangeTypes)); + RPackNum::RangesToVec( origs, mOrig ); + RPackNum::getSize( origs ); + } + + template + AnonymousRange::AnonymousRange(std::shared_ptr... origs) : + RangeInterface() + { + auto rst = std::make_tuple(origs...); + mOrig.resize(sizeof...(RangeTypes)); + RPackNum::RangesToVec( rst, mOrig ); + RPackNum::getSize( rst ); + } + + size_t AnonymousRange::get(size_t pos) const + { + return pos; + } + + size_t AnonymousRange::getMeta(size_t metaPos) const + { + return metaPos; + } + + size_t AnonymousRange::size() const + { + return mSize; + } + + size_t AnonymousRange::dim() const + { + return 1; + } + + typename AnonymousRange::IndexType AnonymousRange::begin() const + { + AnonymousIndex i( std::dynamic_pointer_cast + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + typename AnonymousRange::IndexType AnonymousRange::end() const + { + AnonymousIndex i( std::dynamic_pointer_cast + ( std::shared_ptr( RB::mThis ) ) ); + i = size(); + return i; + } + + // put this in the interface class !!! + std::shared_ptr AnonymousRange::index() const + { + typedef IndexWrapper IW; + return std::make_shared + (std::make_shared + ( std::dynamic_pointer_cast + ( std::shared_ptr( RB::mThis ) ) ) ); + } +} + +#endif diff --git a/src/include/ranges/container_range.h b/src/include/ranges/container_range.h new file mode 100644 index 0000000..f2f0c8c --- /dev/null +++ b/src/include/ranges/container_range.h @@ -0,0 +1,497 @@ +// -*- C++ -*- + +#ifndef __container_range_h__ +#define __container_range_h__ + +#include +#include +#include + +//#include "base_def.h" +#include "ranges/range_base.h" +#include "ranges/index_base.h" + +#include "rpack_num.h" + +namespace MultiArrayTools +{ + + template + class ContainerIndex : public IndexInterface, + std::tuple > + { + public: + + typedef IndexInterface, + std::tuple > IB; + typedef std::tuple MetaType; + typedef std::tuple...> IndexPack; + typedef ContainerRange RangeType; + + static IndexType sType() { return IndexType::CONT; } + static size_t sDim() { return sizeof...(Indices); } + static size_t totalDim() { return mkTotalDim(); } + + private: + + bool mExternControl = false; + IndexPack mIPack; + std::array mBlockSizes; + + public: + + ContainerIndex() = delete; + + template + ContainerIndex(const std::shared_ptr& range); + + template + auto get() const -> decltype( *std::get( mIPack ) )&; + + template + auto getPtr() const -> decltype( std::get( mIPack ) )&; + + const IndexPack& pack() const { return mIPack; } + + ContainerIndex& sync(); // recalculate 'IB::mPos' when externalControl == true + ContainerIndex& operator()(const std::shared_ptr&... inds); // control via external indices + ContainerIndex& operator()(); // -> sync; just to shorten the code + + // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== + + IndexType type() const; + + ContainerIndex& operator++(); + ContainerIndex& operator--(); + + ContainerIndex& operator=(size_t pos); + + int pp(std::intptr_t idxPtrNum); + int mm(std::intptr_t idxPtrNum); + + MetaType meta(); + ContainerIndex& at(const MetaType& metaPos); + + size_t dim(); + bool first(); + bool last(); + + std::shared_ptr range(); + + template + auto getPtr() -> decltype( std::get( mIPack ) )&; + + std::shared_ptr getVPtr(size_t n); + size_t getStepSize(size_t n); + + std::vector infoVec() const; + + std::string id() const; + void print(size_t offset); + + template + auto ifor(Exprs exs) const + -> decltype(RPackNum::mkFor(mIPack, exs)); + + template + auto iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)); + + }; + + + template + class ContainerRangeFactory : public RangeFactoryBase + { + public: + + typedef ContainerRange oType; + + ContainerRangeFactory(); + ContainerRangeFactory(const std::shared_ptr&... rs); + ContainerRangeFactory(const typename ContainerRange::SpaceType& space); + + virtual std::shared_ptr create() override; + + protected: + + }; + + template + class ContainerRange : public RangeInterface > + { + public: + + typedef RangeBase RB; + typedef std::tuple...> SpaceType; + typedef ContainerIndex IndexType; + //typedef typename RangeInterface >::IndexType IndexType; + + protected: + ContainerRange() = default; + ContainerRange(const ContainerRange& in) = delete; + ContainerRange& operator=(const ContainerRange& in) = delete; + + ContainerRange(const std::shared_ptr&... rs); + ContainerRange(const SpaceType& space); + + SpaceType mSpace; + + public: + static const size_t sdim = sizeof...(Ranges); + + virtual size_t dim() const override; + virtual size_t size() const override; + + template + auto get() const -> decltype( *std::get( mSpace ) )&; + + template + auto getPtr() const -> decltype( std::get( mSpace ) )&; + + const SpaceType& space() const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + + virtual std::shared_ptr index() const override; + + friend ContainerRangeFactory; + + static constexpr bool defaultable = false; + static constexpr size_t ISSTATIC = SubProp::ISSTATIC; + static constexpr size_t SIZE = SubProp::SIZE; + }; + +} // end namespace MultiArrayTools + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + namespace + { + using namespace MultiArrayHelper; + } + + /********************** + * ContainerIndex * + **********************/ + + template + template + ContainerIndex::ContainerIndex(const std::shared_ptr& range) : + IndexInterface,std::tuple >(range, 0) + { + RPackNum::construct(mIPack, *range); + IB::mPos = RPackNum::makePos(mIPack); + std::get(mBlockSizes) = 1; + RPackNum::initBlockSizes(mBlockSizes, mIPack); + } + + template + ContainerIndex& ContainerIndex::sync() + { + if(mExternControl){ + IB::mPos = RPackNum::makePos(mIPack); + //VCHECK(id()); + //VCHECK(sizeof...(Indices)); + //assert(IB::mPos < IB::max()); + } + return *this; + } + + template + template + auto ContainerIndex::get() const -> decltype( *std::get( mIPack ) )& + { + return *std::get( mIPack ); + } + + template + template + auto ContainerIndex::getPtr() const -> decltype( std::get( mIPack ) )& + { + return std::get( mIPack ); + } + + template + ContainerIndex& ContainerIndex::operator()(const std::shared_ptr&... inds) + { + RPackNum::swapIndices(mIPack, inds...); + mExternControl = true; + return sync(); + } + + template + ContainerIndex& ContainerIndex::operator()() + { + return sync(); + } + + template + IndexType ContainerIndex::type() const { return IndexType::CONT; } + + template + ContainerIndex& ContainerIndex::operator++() + { + if(mExternControl){ + IB::mPos = RPackNum::makePos(mIPack); + } + RPackNum::pp( mIPack ); + ++IB::mPos; + return *this; + } + + template + ContainerIndex& ContainerIndex::operator--() + { + if(mExternControl){ + IB::mPos = RPackNum::makePos(mIPack); + } + RPackNum::mm( mIPack ); + --IB::mPos; + return *this; + + } + + template + ContainerIndex& ContainerIndex::operator=(size_t pos) + { + IB::mPos = pos; + RPackNum::setIndexPack(mIPack, pos); + return *this; + } + + template + int ContainerIndex::pp(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); + IB::mPos += tmp; + return tmp; + } + + template + int ContainerIndex::mm(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); + IB::mPos -= tmp; + return tmp; + } + + template + typename ContainerIndex::MetaType ContainerIndex::meta() + { + MetaType metaTuple; + RPackNum::getMetaPos(metaTuple, mIPack); + return metaTuple; + } + + template + ContainerIndex& ContainerIndex::at(const MetaType& metaPos) + { + RPackNum::setMeta(mIPack, metaPos); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + + template + size_t ContainerIndex::dim() + { + return sizeof...(Indices); + } + + template + bool ContainerIndex::first() + { + return IB::pos() == 0; + } + + template + bool ContainerIndex::last() + { + return IB::pos() == IB::mMax - 1; + } + + template + std::shared_ptr::RangeType> + ContainerIndex::range() + { + return std::dynamic_pointer_cast( IB::mRangePtr ); + } + + template + template + auto ContainerIndex::getPtr() -> decltype( std::get( mIPack ) )& + { + return std::get( mIPack ); + } + + template + std::shared_ptr ContainerIndex::getVPtr(size_t n) + { + if(n >= sizeof...(Indices)){ + assert(0); + // throw !! + } + ContainerIndex const* t = this; + return RPackNum::getIndexPtr(*t, n); + } + + template + size_t ContainerIndex::getStepSize(size_t n) + { + if(n >= sizeof...(Indices)){ + assert(0); + // throw !! + } + return mBlockSizes[n+1]; + } + + template + std::vector ContainerIndex::infoVec() const + { + std::vector out; + out.reserve(sizeof...(Indices)); + RPackNum::buildInfoVec(out, mIPack, mBlockSizes); + return std::move( out ); + } + + template + std::string ContainerIndex::id() const + { + return std::string("con") + std::to_string(IB::mId); + } + + template + void ContainerIndex::print(size_t offset) + { + if(offset == 0){ + std::cout << " === " << std::endl; + } + for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } + std::cout << id() << "[" << reinterpret_cast(this) << "]" + << "(" << IB::mRangePtr << "): " << meta() << std::endl; + RPackNum::printIndex(mIPack, offset+1); + } + + template + template + auto ContainerIndex::ifor(Exprs exs) const + -> decltype(RPackNum::mkFor(mIPack, exs)) + { + return RPackNum::mkFor(mIPack, exs); + } + + template + template + auto ContainerIndex::iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)) + { + return RPackNum::mkForh(mIPack, exs); + } + + + /***************************** + * ContainerRangeFactory * + *****************************/ + + template + ContainerRangeFactory::ContainerRangeFactory(const std::shared_ptr&... rs) + { + mProd = std::shared_ptr >( new ContainerRange( rs... ) ); + } + + template + ContainerRangeFactory:: + ContainerRangeFactory(const typename ContainerRange::SpaceType& space) + { + mProd = std::shared_ptr >( new ContainerRange( space ) ); + } + + template + std::shared_ptr ContainerRangeFactory::create() + { + setSelf(); + return mProd; + } + + /********************** + * ContainerRange * + **********************/ + + template + ContainerRange::ContainerRange(const std::shared_ptr&... rs) : + mSpace( std::make_tuple( rs... ) ) {} + + template + ContainerRange::ContainerRange(const SpaceType& space) : mSpace( space ) {} + + template + size_t ContainerRange::dim() const + { + return sizeof...(Ranges); + } + + template + size_t ContainerRange::size() const + { + return RPackNum::getSize(mSpace); + } + + template + template + auto ContainerRange::get() const -> decltype( *std::get( mSpace ) )& + { + return *std::get( mSpace ); + } + + template + template + auto ContainerRange::getPtr() const -> decltype( std::get( mSpace ) )& + { + return std::get( mSpace ); + } + + template + const typename ContainerRange::SpaceType& ContainerRange::space() const + { + return mSpace; + } + + template + typename ContainerRange::IndexType ContainerRange::begin() const + { + ContainerIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + template + typename ContainerRange::IndexType ContainerRange::end() const + { + ContainerIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = size(); + return i; + } + + template + std::shared_ptr ContainerRange::index() const + { + typedef IndexWrapper IW; + return std::make_shared + ( std::make_shared + ( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ) ); + } + +} // end namespace MultiArrayTools + + +#endif diff --git a/src/include/ranges/index_base.h b/src/include/ranges/index_base.h new file mode 100644 index 0000000..99b6b0f --- /dev/null +++ b/src/include/ranges/index_base.h @@ -0,0 +1,157 @@ +// -*- C++ -*- + +#ifndef __index_base_h__ +#define __index_base_h__ + +#include +#include +#include + +#include "rbase_def.h" +#include "range_base.h" +#include "index_type.h" +#include "vindex_wrapper.h" +#include "index_info.h" + +#include "xfor/xfor.h" + +namespace MultiArrayTools +{ + + template + class IndexInterface + { + public: + //typedef typename I::RangeType RangeType; + + //DEFAULT_MEMBERS(IndexInterface); + + I& THIS() { return static_cast(*this); } + I const& THIS() const { return static_cast(*this); } + + ~IndexInterface() = default; + + IndexType type() const { return THIS().type(); } + + I& operator=(size_t pos) { return THIS() = pos; } + I& operator++() { return THIS()++; } + I& operator--() { return THIS()--;} + + int pp(std::intptr_t idxPtrNum) { return THIS().pp(idxPtrNum); } + int mm(std::intptr_t idxPtrNum) { return THIS().mm(idxPtrNum); } + + bool operator==(const IndexInterface& in) const; + bool operator!=(const IndexInterface& in) const; + + size_t dim() const { return THIS().dim(); } + size_t pos() const; + size_t max() const; + + bool last() const { return THIS().last(); } + bool first() const { return THIS().first(); } + + + std::shared_ptr vrange() const { return mRangePtr; } + /*auto range() const -> decltype( I::S_range(THIS()) ) { return I::S_range(THIS()); } + + template + auto getPtr() const -> decltype(I::template S_get(THIS())) + { return I::template S_get(THIS()); } + */ + std::shared_ptr getVPtr(size_t n) const { return THIS().getVPtr(n); } + + std::vector infoVec() const { return THIS().infoVec(); } + + size_t getStepSize(size_t n) const { return THIS().getStepSize(n); } + + operator size_t() const; + + std::string id() const { return THIS().id(); } + + MetaType meta() const { return THIS().meta(); } + I& at(const MetaType& meta) { return THIS().at(meta); } + + void print(size_t offset = 0) const { THIS().print(offset); } + + IndexInfo info() const { return IndexInfo(THIS()); } + + // CHECK / IMPLEMENT !!!!!! + template + auto ifor(const Expr ex) const -> decltype(THIS().template ifor(ex)) + { return THIS().template ifor(ex); } + + template + auto iforh(const Expr ex) const -> decltype(THIS().template iforh(ex)) + { return THIS().template iforh(ex); } + + private: + + friend I; + + IndexInterface() { mId = indexId(); } + IndexInterface(const IndexInterface& in) = default; + IndexInterface& operator=(const IndexInterface& in) = default; + IndexInterface(IndexInterface&& in) = default; + IndexInterface& operator=(IndexInterface&& in) = default; + + IndexInterface(const std::shared_ptr& range, size_t pos); + + std::shared_ptr mRangePtr; + size_t mPos; + size_t mId; + size_t mMax; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + /********************** + * IndexInterface * + **********************/ + + template + IndexInterface::IndexInterface(const std::shared_ptr& range, + size_t pos) : mRangePtr(range), + mPos(pos), + mMax(mRangePtr->size()) + { + mId = indexId(); + } + + template + bool IndexInterface::operator==(const IndexInterface& in) const + { + return in.mPos == mPos and in.mRangePtr.get() == mRangePtr.get(); + } + + template + bool IndexInterface::operator!=(const IndexInterface& in) const + { + return in.mPos != mPos or in.mRangePtr.get() != mRangePtr.get(); + } + + template + size_t IndexInterface::pos() const + { + return mPos; + } + + template + size_t IndexInterface::max() const + { + return mMax; + } + + template + IndexInterface::operator size_t() const + { + return pos(); + } +} + +#endif diff --git a/src/include/ranges/index_info.h b/src/include/ranges/index_info.h new file mode 100644 index 0000000..01efba3 --- /dev/null +++ b/src/include/ranges/index_info.h @@ -0,0 +1,103 @@ +// -*- C++ -*- + +#ifndef __index_info_h__ +#define __index_info_h__ + +#include +#include +#include +#include +#include "vindex_base.h" +#include "index_type.h" + +namespace MultiArrayTools +{ + class IndexInfo; + + class IndexInfo + { + public: + + IndexInfo(IndexInfo&& in) = default; + IndexInfo& operator=(IndexInfo&& in) = default; + IndexInfo(const IndexInfo& in) = default; + IndexInfo& operator=(const IndexInfo& in) = default; + + template + IndexInfo(const IndexClass& ind, size_t stepSize = 1); + + template + IndexInfo& reassign(const IndexClass& ind, size_t stepSize = 1); + + bool operator==(const IndexInfo& in) const; + bool operator!=(const IndexInfo& in) const; + + bool operator<=(const IndexInfo& in) const; + bool operator<(const IndexInfo& in) const; + bool operator>(const IndexInfo& in) const; + bool operator>=(const IndexInfo& in) const; + + + const IndexInfo* getPtr(size_t inum) const; + std::intptr_t getPtrNum() const; + size_t dim() const; + size_t max() const; + size_t getStepSize(size_t inum) const; + size_t getStepSize() const; + IndexType type() const; + + private: + + IndexInfo() = default; + + std::vector mNext; + std::intptr_t mPtrNum; + size_t mDim; + size_t mMax; + size_t mStepSize; + IndexType mType; + }; + + template + IndexInfo::IndexInfo(const IndexClass& ind, size_t stepSize) : + mNext(ind.infoVec()), + mPtrNum( reinterpret_cast( &ind ) ), + mDim(ind.vrange()->dim()), + mMax(ind.max()), + mStepSize(stepSize), + mType(ind.type()) + {} + + template + IndexInfo& IndexInfo::reassign(const IndexClass& ind, size_t stepSize) + { + IndexInfo ii(ind, stepSize); + (*this) = std::move(ii); + return *this; + } + + std::vector getRootIndices(const IndexInfo& info); + + inline size_t getStepSize(const IndexInfo& ii, std::intptr_t j) + { + if(ii.type() == IndexType::SINGLE){ + return ii.getPtrNum() == j ? 1 : 0; + } + else { + size_t ss = 0; + size_t sx = 1; + for(size_t i = 0; i != ii.dim(); ++i){ + const IndexInfo& itmp = *ii.getPtr(ii.dim()-i-1); + const size_t max = itmp.max(); + const size_t tmp = getStepSize(itmp, j); + ss += tmp * sx; + sx *= max; + } + return ss; + } + } + + size_t getStepSize(const std::vector& iv, std::intptr_t j); +} // end namespace MultiArrayTools + +#endif diff --git a/src/include/ranges/index_type.h b/src/include/ranges/index_type.h new file mode 100644 index 0000000..6d8c52a --- /dev/null +++ b/src/include/ranges/index_type.h @@ -0,0 +1,14 @@ + +#ifndef __index_type_h__ +#define __index_type_h__ + +namespace MultiArrayTools +{ + enum class IndexType{ + SINGLE = 0, + MULTI = 1, + CONT = 2 + }; +} + +#endif diff --git a/src/include/ranges/multi_range.h b/src/include/ranges/multi_range.h new file mode 100644 index 0000000..c6d27fe --- /dev/null +++ b/src/include/ranges/multi_range.h @@ -0,0 +1,543 @@ +// -*- C++ -*- + +#ifndef __multi_range_h__ +#define __multi_range_h__ + +#include +#include +#include + +//#include "base_def.h" +#include "ranges/range_base.h" +#include "ranges/index_base.h" + +#include "rpack_num.h" + +namespace MultiArrayTools +{ + namespace + { + using namespace MultiArrayHelper; + } + + template + class MultiIndex : public IndexInterface, + std::tuple > + { + public: + + typedef IndexInterface, + std::tuple > IB; + typedef std::tuple...> IndexPack; + typedef std::tuple MetaType; + typedef MultiRange RangeType; + + static IndexType sType() { return IndexType::MULTI; } + static size_t sDim() { return sizeof...(Indices); } + static size_t totalDim() { return mkTotalDim(); } + + private: + + IndexPack mIPack; + std::array mBlockSizes; + + public: + + const IndexPack& pack() const { return mIPack; } + + MultiIndex() = delete; + + // NO DEFAULT HERE !!! + // ( have to assign sub-indices (ptr!) correctly ) + //MultiIndex(const MultiIndex& in); + //MultiIndex& operator=(const MultiIndex& in); + MultiIndex& operator=(ContainerIndex& ci); + + template + MultiIndex(const std::shared_ptr& range); + + template + MultiIndex& up(); + + template + MultiIndex& down(); + + template + auto get() const -> decltype( *std::get( mIPack ) )&; + + template + auto getPtr() const -> decltype( std::get( mIPack ) )&; + + // raplace instances (in contrast to its analogon in ContainerIndex + // MultiIndices CANNOT be influences be its subindices, so there is + // NO foreign/external controll) + // Do NOT share index instances between two or more MultiIndex instances + MultiIndex& operator()(std::shared_ptr&... indices); + + // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== + + IndexType type() const; + + MultiIndex& operator=(size_t pos); + + MultiIndex& operator++(); + MultiIndex& operator--(); + + int pp(std::intptr_t idxPtrNum); + int mm(std::intptr_t idxPtrNum); + + MetaType meta(); + MultiIndex& at(const MetaType& metaPos); + + size_t dim(); + bool first(); + bool last(); + std::shared_ptr range(); + + template + auto getPtr() -> decltype( std::get( mIPack ) )&; + + std::shared_ptr getVPtr(size_t n); + size_t getStepSize(size_t n); + + std::vector infoVec() const; + + std::string id() const; + void print(size_t offset); + + template + auto ifor(Exprs exs) const + -> decltype(RPackNum::mkFor(mIPack, exs)); + + template + auto iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)); + + }; + + /************************* + * MultiRangeFactory * + *************************/ + + template + class MultiRangeFactory : public RangeFactoryBase + { + public: + typedef MultiRange oType; + + MultiRangeFactory() = delete; + MultiRangeFactory(const std::shared_ptr&... rs); + MultiRangeFactory(const typename MultiRange::SpaceType& space); + MultiRangeFactory(const std::shared_ptr >& cr); + + virtual std::shared_ptr create() override; + }; + + /****************** + * MultiRange * + ******************/ + + template + class MultiRange : public RangeInterface > + { + public: + typedef RangeBase RB; + typedef std::tuple...> SpaceType; + typedef MultiIndex IndexType; + //typedef typename RangeInterface >::IndexType IndexType; + + protected: + MultiRange() = delete; + MultiRange(const MultiRange& in) = delete; + MultiRange& operator=(const MultiRange& in) = delete; + + MultiRange(const std::shared_ptr&... rs); + MultiRange(const SpaceType& space); + + SpaceType mSpace; + + public: + + static const size_t sdim = sizeof...(Ranges); + + template + auto get() const -> decltype( *std::get( mSpace ) )&; + + template + auto getPtr() const -> decltype( std::get( mSpace ) )&; + + virtual size_t dim() const override; + virtual size_t size() const override; + + const SpaceType& space() const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + + virtual std::shared_ptr index() const override; + + friend MultiRangeFactory; + + static constexpr bool defaultable = false; + static constexpr size_t ISSTATIC = SubProp::ISSTATIC; + static constexpr size_t SIZE = SubProp::SIZE; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + + namespace + { + using namespace MultiArrayHelper; + } + + /****************** + * MultiIndex * + ******************/ + + /* + template + MultiIndex::MultiIndex(const MultiIndex& in) : + IndexInterface >(in) + { + RPackNum::copy(mIPack, in); + IB::mPos = RPackNum::makePos(mIPack); + } + + template + MultiIndex& MultiIndex::operator=(const MultiIndex& in) + { + IndexI::operator=(in); + RPackNum::copy(mIPack, in); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + */ + template + MultiIndex& MultiIndex::operator=(ContainerIndex& ci) + { + RPackNum::copyInst(mIPack, ci); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + + template + template + MultiIndex::MultiIndex(const std::shared_ptr& range) : + IndexInterface,std::tuple >(range, 0) + { + RPackNum::construct(mIPack, *range); + IB::mPos = RPackNum::makePos(mIPack); + std::get(mBlockSizes) = 1; + RPackNum::initBlockSizes(mBlockSizes, mIPack); // has one more element! + } + + template + template + MultiIndex& MultiIndex::up() + { + static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); + IB::mPos += RPackNum::blockSize( mIPack ); + RPackNum::pp( mIPack ); + return *this; + } + + template + template + MultiIndex& MultiIndex::down() + { + static_assert(DIR < sizeof...(Indices), "DIR exceeds number of sub-indices"); + IB::mPos -= RPackNum::blockSize( mIPack ); + RPackNum::mm( mIPack ); + return *this; + } + + template + template + auto MultiIndex::get() const -> decltype( *std::get( mIPack ) )& + { + return *std::get(mIPack); + } + + template + template + auto MultiIndex::getPtr() const -> decltype( std::get( mIPack ) )& + { + return std::get(mIPack); + } + + template + MultiIndex& MultiIndex::operator()(std::shared_ptr&... indices) + { + RPackNum::swapIndices(mIPack, indices...); + RPackNum::setIndexPack(mIPack, IB::mPos); + return *this; + } + + template + IndexType MultiIndex::type() const + { + return IndexType::MULTI; + } + + template + MultiIndex& MultiIndex::operator=(size_t pos) + { + IB::mPos = pos; + RPackNum::setIndexPack(mIPack, pos); + return *this; + } + + template + MultiIndex& MultiIndex::operator++() + { + RPackNum::pp( mIPack ); + ++IB::mPos; + return *this; + } + + template + MultiIndex& MultiIndex::operator--() + { + RPackNum::mm( mIPack ); + --IB::mPos; + return *this; + } + + template + int MultiIndex::pp(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::pp(mIPack, mBlockSizes, idxPtrNum); + IB::mPos += tmp; + return tmp; + } + + template + int MultiIndex::mm(std::intptr_t idxPtrNum) + { + int tmp = RPackNum::mm(mIPack, mBlockSizes, idxPtrNum); + IB::mPos -= tmp; + return tmp; + } + + template + typename MultiIndex::MetaType MultiIndex::meta() + { + MetaType metaTuple; + RPackNum::getMetaPos(metaTuple, mIPack); + return metaTuple; + } + + template + MultiIndex& MultiIndex::at(const MetaType& metaPos) + { + RPackNum::setMeta(mIPack, metaPos); + IB::mPos = RPackNum::makePos(mIPack); + return *this; + } + + template + size_t MultiIndex::dim() + { + return sizeof...(Indices); + } + + template + bool MultiIndex::first() + { + return IB::mPos == 0; + } + + template + bool MultiIndex::last() + { + return IB::mPos == IB::mMax - 1; + } + + template + std::shared_ptr::RangeType> + MultiIndex::range() + { + return std::dynamic_pointer_cast( IB::mRangePtr ); + } + + template + template + auto MultiIndex::getPtr() -> decltype( std::get( mIPack ) )& + { + return std::get(mIPack); + } + + template + std::shared_ptr MultiIndex::getVPtr(size_t n) + { + if(n >= sizeof...(Indices)){ + assert(0); + // throw !! + } + MultiIndex const* t = this; + return RPackNum::getIndexPtr(*t, n); + } + + template + size_t MultiIndex::getStepSize(size_t n) + { + if(n >= sizeof...(Indices)){ + assert(0); + // throw !! + } + return mBlockSizes[n+1]; + } + + template + std::vector MultiIndex::infoVec() const + { + std::vector out; + out.reserve(sizeof...(Indices)); + RPackNum::buildInfoVec(out, mIPack, mBlockSizes); + return std::move( out ); + } + + template + std::string MultiIndex::id() const + { + return std::string("mul") + std::to_string(IB::mId); + } + + template + void MultiIndex::print(size_t offset) + { + if(offset == 0){ + std::cout << " === " << std::endl; + } + for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } + std::cout << id() << "[" << reinterpret_cast(this) + << "]" << "(" << IB::mRangePtr << "): " << meta() << std::endl; + RPackNum::printIndex(mIPack, offset+1); + } + + template + template + auto MultiIndex::ifor(Exprs exs) const + -> decltype(RPackNum::mkFor(mIPack, exs)) + { + return RPackNum::mkFor(mIPack, exs); + } + + template + template + auto MultiIndex::iforh(Exprs exs) const + -> decltype(RPackNum::mkForh(mIPack, exs)) + { + return RPackNum::mkForh(mIPack, exs); + } + + /************************* + * MultiRangeFactory * + *************************/ + + template + MultiRangeFactory::MultiRangeFactory(const std::shared_ptr&... rs) + { + mProd = std::shared_ptr< MultiRange >( new MultiRange( rs... ) ); + } + + template + MultiRangeFactory::MultiRangeFactory(const typename MultiRange::SpaceType& st) + { + mProd = std::shared_ptr< MultiRange >( new MultiRange( st ) ); + } + + template + MultiRangeFactory::MultiRangeFactory(const std::shared_ptr >& cr) + { + mProd = std::shared_ptr< MultiRange >( new MultiRange( cr->space() ) ); + } + + template + std::shared_ptr MultiRangeFactory::create() + { + setSelf(); + return mProd; + } + + /****************** + * MultiRange * + ******************/ + + template + MultiRange::MultiRange(const std::shared_ptr&... rs) : mSpace(std::make_tuple(rs...)) {} + + template + MultiRange::MultiRange(const SpaceType& space) : mSpace( space ) {} + + template + template + auto MultiRange::get() const -> decltype( *std::get( mSpace ) )& + { + return *std::get(mSpace); + } + + template + template + auto MultiRange::getPtr() const -> decltype( std::get( mSpace ) )& + { + return std::get(mSpace); + } + + template + size_t MultiRange::dim() const + { + return sdim; + } + + template + size_t MultiRange::size() const + { + return RPackNum::getSize(mSpace); + } + + template + const typename MultiRange::SpaceType& MultiRange::space() const + { + return mSpace; + } + + template + typename MultiRange::IndexType MultiRange::begin() const + { + MultiIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + template + typename MultiRange::IndexType MultiRange::end() const + { + MultiIndex + i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis )) ); + i = size(); + return i; + } + + template + std::shared_ptr MultiRange::index() const + { + typedef IndexWrapper IW; + return std::make_shared + ( std::make_shared + ( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ) ); + } +} + +#endif diff --git a/src/include/ranges/range_base.h b/src/include/ranges/range_base.h new file mode 100644 index 0000000..a0f38c4 --- /dev/null +++ b/src/include/ranges/range_base.h @@ -0,0 +1,93 @@ +// -*- C++ -*- + +#ifndef __range_base_h__ +#define __range_base_h__ + +#include +#include +#include + +#include "base_def.h" + +namespace MultiArrayTools +{ + class RangeBase; +} +#include "vindex_base.h" + +namespace MultiArrayTools +{ + + size_t indexId(); + + enum class SpaceType + { + NONE = 0, + ANY = 1, +#define include_range_type(x,n) x = n, +#include "range_types/header.h" +#undef include_range_type + }; + + class RangeFactoryBase + { + public: + + RangeFactoryBase() = default; + virtual ~RangeFactoryBase() = default; + + // should return mProd !! + virtual std::shared_ptr create() = 0; + + protected: + + std::shared_ptr mProd; + + // call this function before returning product !! + void setSelf(); + }; + + class RangeBase + { + public: + + virtual ~RangeBase() = default; + + virtual size_t size() const = 0; + virtual size_t dim() const = 0; + + virtual std::shared_ptr index() const = 0; + + bool operator==(const RangeBase& in) const; + bool operator!=(const RangeBase& in) const; + + //virtual bool regular() const = 0; // integer distance (e.g. 2,3,4,...) + //virtual bool linear() const = 0; // 1dim valuable (e.g. 2.45, 3.12, 3.56,...) + //virtual bool multi() const = 0; // mdim + //virtual bool maplike() const = 0; // meta type is ~ MultiArray + + friend RangeFactoryBase; + + protected: + + RangeBase() = default; + std::weak_ptr mThis; + }; + + template + class RangeInterface : public RangeBase + { + public: + + typedef Index IndexType; + + virtual Index begin() const = 0; + virtual Index end() const = 0; + + protected: + RangeInterface() = default; + }; + +} + +#endif diff --git a/src/include/ranges/range_types/header.h b/src/include/ranges/range_types/header.h new file mode 100644 index 0000000..0632275 --- /dev/null +++ b/src/include/ranges/range_types/header.h @@ -0,0 +1,23 @@ + +#ifdef include_range_type +#define __incl_this__ +#endif +#ifdef __single_range_h__ +// singel_range is template which is specialized here +// therefore it must be defined before... +#define __incl_this__ +#endif + +#ifdef __incl_this__ + +#define __ranges_header__ +//#ifndef __ranges_header__ +//#define __ranges_header__ + +#include "spin_range.h" + +#undef __ranges_header__ +//#endif +#endif + +#undef __incl_this__ diff --git a/src/include/ranges/range_types/spin_range.h b/src/include/ranges/range_types/spin_range.h new file mode 100644 index 0000000..77be683 --- /dev/null +++ b/src/include/ranges/range_types/spin_range.h @@ -0,0 +1,149 @@ + + +#ifdef include_range_type +include_range_type(SPIN,2) +#else + +#ifdef __ranges_header__ +// assert, that this is only used within range_types/header.h + +//#ifndef __spin_range_h__ +//#define __spin_range_h__ + +namespace MultiArrayTools +{ + typedef SingleIndex SpinIndex; + + template <> + class SingleRangeFactory : public RangeFactoryBase + { + public: + + typedef SingleRange oType; + + SingleRangeFactory(); + std::shared_ptr create(); + + }; + + template <> + class SingleRange : public RangeInterface + { + public: + typedef RangeBase RB; + typedef typename RangeInterface >::IndexType IndexType; + + virtual size_t size() const override; + virtual size_t dim() const override; + + size_t get(size_t pos) const; + size_t getMeta(size_t metaPos) const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + virtual std::shared_ptr index() const override; + + friend SingleRangeFactory; + + static constexpr bool defaultable = true; + static constexpr size_t mSpinNum = 4; + + static constexpr size_t ISSTATIC = 1; + static constexpr size_t SIZE = mSpinNum; + + static SingleRangeFactory factory() + { return SingleRangeFactory(); } + + protected: + + SingleRange() = default; + SingleRange(const SingleRange& in) = delete; + + //SingleRange(size_t spinNum); + }; + + typedef SingleRange SpinRange; + typedef SingleRangeFactory SpinRF; +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + /******************** + * SingleRange * + ********************/ + + SingleRangeFactory::SingleRangeFactory() + { + // Quasi Singleton + if(not mProd){ + mProd = std::shared_ptr( new SingleRange() ); + setSelf(); + } + } + + std::shared_ptr SingleRangeFactory::create() + { + return mProd; + } + + /******************** + * SingleRange * + ********************/ + + size_t SingleRange::get(size_t pos) const + { + return pos; + } + + size_t SingleRange::getMeta(size_t metaPos) const + { + return metaPos; + } + + size_t SingleRange::size() const + { + return mSpinNum; + } + + size_t SingleRange::dim() const + { + return 1; + } + + typename SingleRange::IndexType SingleRange::begin() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + typename SingleRange::IndexType SingleRange::end() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = size(); + return i; + } + + // put this in the interface class !!! + std::shared_ptr SingleRange::index() const + { + typedef IndexWrapper IW; + return std::make_shared + ( std::make_shared + ( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ) ); + } + +} + +//#endif // #ifndef __spin_range_h__ + +#endif // #ifdef __ranges_header__ + +#endif // #ifdef include_range_type diff --git a/src/include/ranges/rbase_def.h b/src/include/ranges/rbase_def.h new file mode 100644 index 0000000..5521720 --- /dev/null +++ b/src/include/ranges/rbase_def.h @@ -0,0 +1,80 @@ +// -*- C++ -*- + +#ifndef __ranges_base_def_h__ +#define __ranges_base_def_h__ + +namespace MultiArrayTools +{ + /*********************** + * Provided Types * + ***********************/ + + // range_base.h + enum class SpaceType; + + // range_base.h + class RangeFactoryBase; + + // range_base.h + class RangeBase; + + // range_base.h + template + class RangeInterface; + + // index_base.h + class VirtualIndexWrapperBase; + typedef VirtualIndexWrapperBase VIWB; + + // index_base.h + template + class IndexWrapper; + + // index_base.h + template + class IndexInterface; + + // single_range.h + template + class SingleRange; + + // single_range.h + template + class SingleRangeFactory; + + // single_range.h + template + class SingleIndex; + + // multi_range.h + template + class MultiRangeFactory; + + // multi_range.h + template + class MultiRange; + + // multi_range.h + template + class MultiIndex; + + // container_range.h + template + class ContainerRangeFactory; + + // container_range.h + template + class ContainerRange; + + // container_range.h + template + class ContainerIndex; + + // anonymous_range.h + class AnonymousRangeFactory; + + // anonymous_range.h + class AnonymousRange; +} + +#endif diff --git a/src/include/ranges/rheader.h b/src/include/ranges/rheader.h new file mode 100644 index 0000000..cc0795f --- /dev/null +++ b/src/include/ranges/rheader.h @@ -0,0 +1,5 @@ + +#include "single_range.h" +#include "multi_range.h" +#include "container_range.h" +//#include "anonymous_range.h" have to fix bug !! diff --git a/src/include/ranges/rpack_num.h b/src/include/ranges/rpack_num.h new file mode 100644 index 0000000..e41f3b3 --- /dev/null +++ b/src/include/ranges/rpack_num.h @@ -0,0 +1,452 @@ + +#ifndef __rpack_num_h__ +#define __rpack_num_h__ + +#include +#include "vindex_wrapper.h" +#include "index_info.h" + +namespace MultiArrayHelper +{ + using namespace MultiArrayTools; + + + template + size_t mkTotalDim() + { + return Index1::totalDim(); + } + + template + size_t mkTotalDim() + { + return Index1::totalDim() * mkTotalDim(); + } + + + template + struct SubProp + { + static constexpr size_t ISSTATIC = RangeType::ISSTATIC & SubProp::ISSTATIC; + static constexpr size_t SIZE = RangeType::SIZE * SubProp::SIZE; + }; + + template <> + struct SubProp + { + static constexpr size_t ISSTATIC = 1; + static constexpr size_t SIZE = 1; + }; + + template + struct RPackNum + { + template + static std::shared_ptr getIndex(const IndexType& in, size_t n) + { + if(n == N){ + return make_viwb( in.template get() ); + } + else { + return RPackNum::getIndex(in, n); + } + } + + template + static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) + { + if(n == N){ + return make_viwb( in.template getPtr() ); + } + else { + return RPackNum::getIndexPtr(in, n); + } + } + + template + static void initBlockSizes(std::array& bs, + std::tuple...>& ip) + { + std::get(bs) = RPackNum::blockSize(ip); + RPackNum::initBlockSizes(bs, ip); + } + + template + static inline void pp(std::tuple...>& ip) + { + auto& si = *std::get(ip); + if(si.last()){ + si = 0; + RPackNum::pp(ip); + } + else { + ++si; + } + } + + template + static inline int pp(std::tuple...>& ip, + std::array& bs, + std::intptr_t idxPtrNum) + { + auto& siPtr = std::get(ip); + //VCHECK(siPtr.id()); + if(reinterpret_cast(siPtr.get()) == idxPtrNum){ + return RPackNum::pp(ip, bs, idxPtrNum); + } + else { + int tmp = siPtr->pp(idxPtrNum); + if(siPtr->pos() == siPtr->max()){ + (*siPtr) = 0; + return RPackNum::pp(ip, bs, idxPtrNum) - siPtr->max() + 1; + } + else { + return tmp * std::get(bs); + } + } + } + + template + static inline void mm(std::tuple...>& ip) + { + auto& si = *std::get(ip); + if(si.first()){ + si = si.max() - 1; + RPackNum::mm(ip); + } + else { + --si; + } + } + + // !!!! + template + static inline int mm(std::tuple...>& ip, + std::array& bs, + std::intptr_t idxPtrNum) + { + auto& siPtr = std::get(ip); + if(reinterpret_cast(siPtr.get()) == idxPtrNum){ + return std::get(bs) + RPackNum::mm(ip, bs, idxPtrNum); + } + else { + if(siPtr->first()){ + (*siPtr) = siPtr->max() - 1; + return RPackNum::mm(ip, bs, idxPtrNum) - siPtr->max() + 1; + } + else { + return siPtr->mm(idxPtrNum); + } + } + } + + template + static size_t getSize(const RangeTuple& rt) + { + return std::get(rt)->size() * RPackNum::getSize(rt); + } + + template + static void getMetaPos(MetaType& target, + const IndexPack& source) + { + std::get(target) = std::get(source)->meta(); + RPackNum::getMetaPos(target, source); + } + + template + static void setMeta(IndexPack& target, const MetaType& source) + { + std::get(target)->at( std::get(source) ); + RPackNum::setMeta(target, source); + } + + template + static void setIndexPack(IndexPack& iPack, size_t pos) + { + auto& i = *std::get(iPack).get(); + const size_t ownPos = pos % i.max(); + i = ownPos; + RPackNum::setIndexPack(iPack, (pos - ownPos) / i.max() ); + } + + template + static void construct(std::tuple...>& ip, + const MRange& range) + { + typedef typename std::remove_reference())>::type SubRangeType; + typedef typename SubRangeType::IndexType SubIndexType; + typedef typename std::remove_reference(ip).get())>::type TypeFromIndexPack; + + static_assert(std::is_same::value, + "inconsiśtent types"); + + std::get(ip) = std::shared_ptr( new SubIndexType( range.template getPtr() ) ); + RPackNum::construct(ip, range); + } + + template class IndexType, class... Indices> + static void copyInst(std::tuple...>& ip, + const IndexType& ind) + { + std::get(ip) = ind.template getPtr() ; + RPackNum::copyInst(ip, ind); + } + + template + static inline size_t makePos(const std::tuple...>& iPtrTup) + { + //const auto& idx = *std::get(iPtrTup); + return std::get(iPtrTup)->pos() + RPackNum::makePos(iPtrTup) * std::get(iPtrTup)->max(); + } + + template + static void swapIndices(Pack& ipack, const std::shared_ptr& nind, + const std::shared_ptr&... ninds) + { + std::get::value-N-1>(ipack) = nind; + RPackNum::swapIndices(ipack, ninds...); + } + + template + static size_t blockSize(const std::tuple...>& pack) + { + return std::get(pack)->max() * RPackNum::blockSize(pack); + } + + + template + static void RangesToVec(const std::tuple...>& rst, + std::vector v) + { + v[N] = std::get(rst); + RPackNum::RangesToVec(rst, v); + } + + template + static void printIndex(const std::tuple...>& ip, size_t offset) + { + std::get(ip)->print(offset); + RPackNum::printIndex(ip, offset); + } + + template + static void checkDefaultable() + { + static_assert( Range::defaultable, "not defaultable" ); + RPackNum::template checkDefaultable(); + } + + template + static void buildInfoVec(std::vector& out, + const std::tuple...>& ip, + const std::array& bs) + { + static const size_t POS = sizeof...(Indices)-N-1; + out.emplace_back(*std::get(ip), std::get(bs)); + RPackNum::buildInfoVec(out, ip, bs); + } + + template + static auto mkFor(const IndexPack& ipack, Exprs exs) + -> decltype(std::get::value-N-1>(ipack) + ->ifor( RPackNum::mkFor(ipack, exs) ) ) + { + return std::get::value-N-1>(ipack) + ->ifor( RPackNum::mkFor(ipack, exs) ); + } + + template + static auto mkForh(const IndexPack& ipack, Exprs exs) + -> decltype(std::get::value-N-1>(ipack) + ->iforh( RPackNum::mkForh(ipack, exs) ) ) + { + return std::get::value-N-1>(ipack) + ->iforh( RPackNum::mkForh(ipack, exs) ); + } + + }; + + + template<> + struct RPackNum<0> + { + template + static std::shared_ptr getIndex(const IndexType& in, size_t n) + { + return make_viwb( in.template get<0>() ); + } + + template + static std::shared_ptr getIndexPtr(const IndexType& in, size_t n) + { + return make_viwb( in.template getPtr<0>() ); + } + + template + static void initBlockSizes(std::array& bs, + std::tuple...>& ip) + { + std::get<0>(bs) = RPackNum::blockSize(ip); + } + + template + static inline void pp(std::tuple...>& ip) + { + auto& si = *std::get<0>(ip); + ++si; + } + + template + static inline int pp(std::tuple...>& ip, + std::array& bs, + std::intptr_t idxPtrNum) + { + auto& siPtr = std::get<0>(ip); + if(reinterpret_cast(siPtr.get()) == idxPtrNum){ + return std::get<0>(bs); + } + else { + int tmp = siPtr->pp(idxPtrNum); + return tmp * std::get<1>(bs); + } + } + + template + static inline void mm(std::tuple...>& ip) + { + auto& si = *std::get<0>(ip); + --si; + } + + template + static inline int mm(std::tuple...>& ip, + std::array& bs, + std::intptr_t idxPtrNum) + { + auto& siPtr = std::get<0>(ip); + if(reinterpret_cast(siPtr.get()) == idxPtrNum){ + return std::get<0>(bs); + //return 1; + } + else { + return siPtr->mm(idxPtrNum); + } + } + + template + static size_t getSize(const RangeTuple& rt) + { + return std::get<0>(rt)->size(); + } + + template + static void getMetaPos(MetaType& target, + const IndexPack& source) + { + std::get<0>(target) = std::get<0>(source)->meta(); + } + + template + static void setMeta(IndexPack& target, const MetaType& source) + { + std::get<0>(target)->at( std::get<0>( source ) ); + } + + template + static void setIndexPack(IndexPack& iPack, size_t pos) + { + auto& i = *std::get<0>(iPack); + const size_t ownPos = pos % i.max(); + i = ownPos; + } + + template + static void construct(std::tuple...>& ip, + const MRange& range) + { + typedef typename std::remove_reference())>::type SubRangeType; + typedef typename SubRangeType::IndexType SubIndexType; + typedef typename std::remove_reference(ip).get())>::type TypeFromIndexPack; + + static_assert(std::is_same::value, + "inconsiśtent types"); + + std::get<0>(ip) = std::shared_ptr( new SubIndexType( range.template getPtr<0>() ) ); + } + + template class IndexType, class... Indices> + static void copyInst(std::tuple...>& ip, + const IndexType& ind) + { + std::get<0>(ip) = ind.template getPtr<0>(); + } + + template + static inline size_t makePos(const std::tuple...>& iPtrTup) + { + return std::get<0>(iPtrTup)->pos(); + } + + template + static void swapIndices(Pack& ipack, const std::shared_ptr& nind) + { + std::get::value-1>(ipack) = nind; + } + + template + static size_t blockSize(const std::tuple...>& pack) + { + return std::get(pack)->max(); + } + + template + static void RangesToVec(const std::tuple...>& rst, + std::vector v) + { + v[0] = std::get<0>(rst); + } + + template + static void printIndex(const std::tuple...>& ip, size_t offset) + { + std::get<0>(ip)->print(offset); + } + + template + static void checkDefaultable() + { + static_assert( Range::defaultable, "not defaultable" ); + } + + template + static void buildInfoVec(std::vector& out, + const std::tuple...>& ip, + const std::array& bs) + { + static const size_t POS = sizeof...(Indices)-1; + out.emplace_back(*std::get(ip), std::get(bs)); + } + + template + static auto mkFor(const IndexPack& ipack, Exprs exs) + -> decltype(std::get::value-1>(ipack) + ->ifor(exs) ) + { + return std::get::value-1>(ipack)->ifor(exs); + } + + template + static auto mkForh(const IndexPack& ipack, Exprs exs) + -> decltype(std::get::value-1>(ipack) + ->iforh(exs) ) + { + return std::get::value-1>(ipack)->iforh(exs); + } + + }; + + +} // end namespace MultiArrayHelper + +#endif diff --git a/src/include/ranges/single_range.h b/src/include/ranges/single_range.h new file mode 100644 index 0000000..f85f7b4 --- /dev/null +++ b/src/include/ranges/single_range.h @@ -0,0 +1,367 @@ +// -*- C++ -*- + +#ifndef __single_range_h__ +#define __single_range_h__ + +#include +#include +#include + +//#include "base_def.h" +#include "ranges/index_base.h" +#include "ranges/range_base.h" + +#include "xfor/xfor.h" + +using MultiArrayHelper::For; + +namespace MultiArrayTools +{ + + template + class SingleIndex : public IndexInterface,U> + { + public: + + typedef IndexInterface,U> IB; + typedef U MetaType; + typedef SingleRange RangeType; + + //DEFAULT_MEMBERS_X(SingleIndex); + + SingleIndex(const std::shared_ptr >& range); + + static IndexType sType() { return IndexType::SINGLE; } + static size_t totalDim() { return 1; } + + // ==== >>>>> STATIC POLYMORPHISM <<<<< ==== + + IndexType type() const; + + SingleIndex& operator=(size_t pos); + SingleIndex& operator++(); + SingleIndex& operator--(); + + int pp(std::intptr_t idxPtrNum); + int mm(std::intptr_t idxPtrNum); + + U meta(); + SingleIndex& at(const U& metaPos); + + size_t dim(); // = 1 + bool last(); + bool first(); + + std::shared_ptr range(); + + template + void getPtr(); + + std::shared_ptr getVPtr(size_t n); + size_t getStepSize(size_t n); + + std::vector infoVec() const; + + std::string id() const; + void print(size_t offset); + + template + auto ifor(Expr ex) const + -> For,Expr>; + + template + auto iforh(Expr ex) const + -> For,Expr,ForType::HIDDEN>; + + }; + + template + class SingleRangeFactory : public RangeFactoryBase + { + public: + + typedef SingleRange oType; + + SingleRangeFactory() = delete; + SingleRangeFactory(const std::vector& space); + std::shared_ptr create(); + + }; + + template + class SingleRange : public RangeInterface > + { + public: + typedef RangeBase RB; + typedef SingleIndex IndexType; + //typedef typename RangeInterface >::IndexType IndexType; + + virtual size_t size() const override; + virtual size_t dim() const override; + + const U& get(size_t pos) const; + size_t getMeta(const U& metaPos) const; + + virtual IndexType begin() const override; + virtual IndexType end() const override; + virtual std::shared_ptr index() const override; + + friend SingleRangeFactory; + + static constexpr bool defaultable = false; + static constexpr size_t ISSTATIC = 0; + static constexpr size_t SIZE = -1; + + + protected: + + SingleRange() = delete; + SingleRange(const SingleRange& in) = delete; + + SingleRange(const std::vector& space); + + std::vector mSpace; + }; + +} + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayTools +{ + /****************** + * SingleIndex * + ******************/ + + template + SingleIndex::SingleIndex(const std::shared_ptr >& range) : + IndexInterface,U>(range, 0) {} + + template + IndexType SingleIndex::type() const + { + return IndexType::SINGLE; + } + + template + SingleIndex& SingleIndex::operator=(size_t pos) + { + IB::mPos = pos; + return *this; + } + + template + SingleIndex& SingleIndex::operator++() + { + ++IB::mPos; + return *this; + } + + template + SingleIndex& SingleIndex::operator--() + { + --IB::mPos; + return *this; + } + + template + int SingleIndex::pp(std::intptr_t idxPtrNum) + { + ++(*this); + return 1; + } + + template + int SingleIndex::mm(std::intptr_t idxPtrNum) + { + --(*this); + return 1; + } + + template + U SingleIndex::meta() + { + return std::dynamic_pointer_cast const>( IB::mRangePtr )->get( IB::pos() ); + } + + template + SingleIndex& SingleIndex::at(const U& metaPos) + { + (*this) = std::dynamic_pointer_cast const>( IB::mRangePtr )->getMeta( metaPos ); + return *this; + } + + template + size_t SingleIndex::dim() // = 1 + { + return 1; + } + + template + bool SingleIndex::last() + { + return IB::mPos == IB::mMax - 1; + } + + template + bool SingleIndex::first() + { + return IB::mPos == 0; + } + + template + std::shared_ptr::RangeType> SingleIndex::range() + { + return std::dynamic_pointer_cast( IB::mRangePtr ); + } + + template + template + void SingleIndex::getPtr() {} + + template + std::shared_ptr SingleIndex::getVPtr(size_t n) + { + return std::shared_ptr(); + } + + template + std::vector SingleIndex::infoVec() const + { + return std::move( std::vector() ); + } + + template + size_t SingleIndex::getStepSize(size_t n) + { + return 1; + } + + template + std::string SingleIndex::id() const + { + return std::string("sin") + std::to_string(IB::mId); + } + + template + void SingleIndex::print(size_t offset) + { + if(offset == 0){ + std::cout << " === " << std::endl; + } + for(size_t j = 0; j != offset; ++j) { std::cout << "\t"; } + std::cout << id() << "[" << reinterpret_cast(this) + << "](" << IB::mRangePtr << "): " << meta() << std::endl; + } + + template + template + auto SingleIndex::ifor(Expr ex) const + -> For,Expr> + { + //static const size_t LAYER = typename Expr::LAYER; + return For,Expr>(this, ex); + } + + template + template + auto SingleIndex::iforh(Expr ex) const + -> For,Expr,ForType::HIDDEN> + { + //static const size_t LAYER = typename Expr::LAYER; + return For,Expr,ForType::HIDDEN>(this, ex); + } + + + /******************** + * SingleRange * + ********************/ + + template + SingleRangeFactory::SingleRangeFactory(const std::vector& space) + { + mProd = std::shared_ptr( new SingleRange( space ) ); + } + + template + std::shared_ptr SingleRangeFactory::create() + { + setSelf(); + return mProd; + } + + /******************** + * SingleRange * + ********************/ + + template + SingleRange::SingleRange(const std::vector& space) : RangeInterface >(), + mSpace(space) {} + + template + const U& SingleRange::get(size_t pos) const + { + return mSpace[pos]; + } + + template + size_t SingleRange::getMeta(const U& metaPos) const + { + size_t cnt = 0; + for(auto& x: mSpace){ + if(x == metaPos){ + return cnt; + } + ++cnt; + } + return cnt; + } + + template + size_t SingleRange::size() const + { + return mSpace.size(); + } + + template + size_t SingleRange::dim() const + { + return 1; + } + + template + typename SingleRange::IndexType SingleRange::begin() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = 0; + return i; + } + + template + typename SingleRange::IndexType SingleRange::end() const + { + SingleIndex i( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ); + i = size(); + return i; + } + + // put this in the interface class !!! + template + std::shared_ptr SingleRange::index() const + { + typedef IndexWrapper IW; + return std::make_shared + ( std::make_shared + ( std::dynamic_pointer_cast > + ( std::shared_ptr( RB::mThis ) ) ) ); + } + +} + +#include "range_types/header.h" + +#endif diff --git a/src/include/ranges/vindex_base.h b/src/include/ranges/vindex_base.h new file mode 100644 index 0000000..114d2e1 --- /dev/null +++ b/src/include/ranges/vindex_base.h @@ -0,0 +1,35 @@ + +#ifndef __vindex_base_h__ +#define __vindex_base_h__ + +//#include "ranges/range_base.h" +#include "ranges/index_type.h" +#include "base_def.h" + +namespace MultiArrayTools +{ + +#ifndef __range_base_h__ + class RangeBase; +#endif + + class VirtualIndexWrapperBase + { + public: + DEFAULT_MEMBERS(VirtualIndexWrapperBase); + + virtual IndexType type() const = 0; + virtual size_t dim() const = 0; + virtual size_t pos() const = 0; + virtual size_t max() const = 0; + virtual std::shared_ptr rangePtr() const = 0; + virtual std::shared_ptr getPtr(size_t n) const = 0; + virtual std::intptr_t getPtrNum() const = 0; + virtual size_t getStepSize(size_t n) const = 0; + }; + + typedef VirtualIndexWrapperBase VIWB; + +} // end namespace MultiArrayTools + +#endif diff --git a/src/include/ranges/vindex_wrapper.h b/src/include/ranges/vindex_wrapper.h new file mode 100644 index 0000000..705269f --- /dev/null +++ b/src/include/ranges/vindex_wrapper.h @@ -0,0 +1,43 @@ + +#ifndef __vindex_wrapper_h__ +#define __vindex_wrapper_h__ + +#include "ranges/vindex_base.h" + +namespace MultiArrayTools +{ + + template + std::shared_ptr > make_viwb(std::shared_ptr idxPtr) + { + return std::make_shared >(idxPtr); + } + + template + class IndexWrapper : public VirtualIndexWrapperBase + { + public: + + DEFAULT_MEMBERS(IndexWrapper); + + IndexWrapper(std::shared_ptr idxPtr) : mIdxPtr(idxPtr) {} + + virtual IndexType type() const override { return mIdxPtr->type(); } + virtual size_t dim() const override { return mIdxPtr->dim(); } + virtual size_t pos() const override { return mIdxPtr->pos(); } + virtual size_t max() const override { return mIdxPtr->max(); } + virtual std::shared_ptr rangePtr() const override { return mIdxPtr->vrange(); } + virtual std::shared_ptr getPtr(size_t n) const override + { return mIdxPtr->getVPtr(n); } + virtual std::intptr_t getPtrNum() const override { return reinterpret_cast( mIdxPtr.get() ); } + virtual size_t getStepSize(size_t n) const override { return mIdxPtr->getStepSize(n); } + + std::shared_ptr get() const { return mIdxPtr; } // unwrap + + private: + std::shared_ptr mIdxPtr; + }; + +} + +#endif diff --git a/src/include/utils.h b/src/include/utils.h new file mode 100644 index 0000000..6e1344c --- /dev/null +++ b/src/include/utils.h @@ -0,0 +1,30 @@ + +#ifndef __utils_h__ +#define __utils_h__ + +#include +#include "pack_num.h" + +namespace MultiArrayHelper +{ + + using namespace MultiArrayTools; + + template + std::ostream& operator<<(std::ostream& out, const std::tuple& tp); + + /*==================* + * TEMPLATE CODE * + *==================*/ + + template + std::ostream& operator<<(std::ostream& out, const std::tuple& tp) + { + PackNum::printTuple(out, tp); + return out; + } + + +} // end namespace MultiArrayHelper + +#endif diff --git a/src/include/xfor/exttype.h b/src/include/xfor/exttype.h new file mode 100644 index 0000000..65718b3 --- /dev/null +++ b/src/include/xfor/exttype.h @@ -0,0 +1,220 @@ + +#ifndef __exttype_h__ +#define __exttype_h__ + +#include + +namespace MultiArrayHelper +{ + + template + class MExt + { + private: + + size_t mExt = 0u; + X mNext; + + public: + + static constexpr size_t NUM = X::NUM + 1; + + MExt() = default; + MExt(const MExt& in) = default; + MExt& operator=(const MExt& in) = default; + MExt(MExt&& in) = default; + MExt& operator=(MExt&& in) = default; + + inline MExt(size_t ext, X next); + + template + inline MExt(size_t y, const Z& z); + + template + inline MExt(const Y& y, const Z& z); + + template + inline MExt(const std::array& arr); + + inline size_t val() const; + inline const X& next() const; + + inline MExt operator+(const MExt& in) const; + inline MExt operator*(size_t in) const; + + template + auto extend(const Y& y) const -> MExt + { return MExt(mExt, mNext.extend(y)); } + + }; + + template <> + class MExt + { + private: + + size_t mExt = 0u; + + public: + + static constexpr size_t NUM = 0; + + MExt() = default; + MExt(const MExt& in) = default; + MExt& operator=(const MExt& in) = default; + MExt(MExt&& in) = default; + MExt& operator=(MExt&& in) = default; + + inline MExt(size_t ext); + + template + inline MExt(size_t y, const Z& z); + + template + inline MExt(const Y& y, const Z& z); + + template + inline MExt(const std::array& arr); + + inline size_t val() const; + inline size_t next() const { return 0; } + + inline MExt operator+(const MExt& in) const; + inline MExt operator*(size_t in) const; + + template + auto extend(const Y& y) const -> MExt + { return MExt(mExt,y); } + + }; + + + template + struct Getter + { + template + static inline size_t get(const ExtType& et) + { + return Getter::get(et.next()); + } + + template + static inline auto getX(const ExtType& et) + -> decltype(Getter::getX(et.next())) + { + return Getter::getX(et.next()); + } + }; + + template <> + struct Getter<0> + { + template + static inline size_t get(const ExtType& et) + { + return et.get(); + } + + template + static inline auto getX(const ExtType& et) + -> ExtType + { + return et; + } + }; + +} // end namespace MultiArrayHelper + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +namespace MultiArrayHelper +{ + + template + inline MExt::MExt(size_t ext, X next) : mExt(ext), mNext(next) {} + + template + template + inline MExt::MExt(const std::array& arr) : + mExt(std::get(arr)), mNext(arr) {} + + template + template + inline MExt::MExt(size_t y, const Z& z) : + mExt(z.val()), mNext(z.val(), z.next()) {} + + template + template + inline MExt::MExt(const Y& y, const Z& z) : + mExt(y.val()), mNext(y.next(), z) {} + + template + inline size_t MExt::val() const + { + return mExt; + } + + template + inline const X& MExt::next() const + { + return mNext; + } + + template + inline MExt MExt::operator+(const MExt& in) const + { + return MExt(mExt + in.val(), mNext + in.next()); + } + + template + inline MExt MExt::operator*(size_t in) const + { + return MExt(mExt * in, mNext * in); + } + + + //template <> + inline MExt::MExt(size_t ext) : mExt(ext) {} + + + //template <> + template + inline MExt::MExt(size_t y, const Z& z) : + mExt(z.val()) {} + + //template <> + template + inline MExt::MExt(const Y& y, const Z& z) : + mExt(y.val()) {} + + + //template <> + template + inline MExt::MExt(const std::array& arr) : + mExt(std::get(arr)) {} + + //template <> + inline size_t MExt::val() const + { + return mExt; + } + + //template <> + inline MExt MExt::operator+(const MExt& in) const + { + return MExt(mExt + in.val()); + } + + //template <> + inline MExt MExt::operator*(size_t in) const + { + return MExt(mExt * in); + } + + +} // end namespace MultiArrayHelper + + +#endif diff --git a/src/include/xfor/for_type.h b/src/include/xfor/for_type.h new file mode 100644 index 0000000..0d2deda --- /dev/null +++ b/src/include/xfor/for_type.h @@ -0,0 +1,18 @@ + +#ifndef __for_type_h__ +#define __for_type_h__ + +namespace MultiArrayHelper +{ + + + enum class ForType { + DEFAULT = 0, + HIDDEN = 1 + }; + + +} // end namespace MultiArrayHelper + + +#endif diff --git a/src/include/xfor/for_utils.h b/src/include/xfor/for_utils.h new file mode 100644 index 0000000..b706c97 --- /dev/null +++ b/src/include/xfor/for_utils.h @@ -0,0 +1,39 @@ + +#ifndef __for_utils_h__ +#define __for_utils_h__ + +#include "ranges/rheader.h" +#include +#include + +namespace MultiArrayHelper +{ + namespace { + template + using to_size_t = size_t; + } + + template + struct XFPackNum + { + template + static inline ETuple mkPos(size_t pos, const ETuple& et, const ETuple& lt, const Args&... args) + { + return std::move( XFPackNum::mkPos(pos, et, lt, std::get(lt) + pos * std::get(et), args...) ); + } + }; + + template <> + struct XFPackNum<0> + { + template + static inline ETuple mkPos(size_t pos, const ETuple& et, const ETuple& lt, const Args&... args) + { + return ETuple(std::get<0>(lt) + pos * std::get<0>(et), args...); + } + + }; + +} // end namespace MultiArrayHelper + +#endif diff --git a/src/include/xfor/xfor.h b/src/include/xfor/xfor.h new file mode 100644 index 0000000..cec68a4 --- /dev/null +++ b/src/include/xfor/xfor.h @@ -0,0 +1,172 @@ + +#ifndef __xfor_h__ +#define __xfor_h__ + +#include +#include +#include +#include "xfor/for_utils.h" +#include "xfor/for_type.h" +#include "xfor/exttype.h" + +namespace MultiArrayHelper +{ + + // 'HIDDEN FOR' CLASS for nested for loops in contractions a.s.o. + // (NO COUNTING OF MASTER POSITION !!!!!) + + template + struct PosForward + { + static inline size_t value(size_t last, size_t max, size_t pos) + { + return last * max + pos; + } + }; + + template <> + struct PosForward + { + static inline size_t value(size_t last, size_t max, size_t pos) + { + return last; + } + }; + + template + struct ForBound + { + template + static inline size_t bound(size_t bound) + { + return bound; + } + }; + + template <> + struct ForBound<1> + { + template + static constexpr size_t bound(size_t bound) + { + return BOUND; + } + }; + + template + class For + { + private: + For() = default; + //For(const For& in) = default; + //For& operator=(const For& in) = default; + + const IndexClass* mIndPtr; + size_t mSPos; + size_t mMax; + Expr mExpr; + + typedef decltype(mExpr.rootSteps()) ExtType; + ExtType mExt; + + public: + + static constexpr size_t LAYER = Expr::LAYER + 1; + static constexpr size_t SIZE = Expr::SIZE; + + For(const For& in) = default; + For& operator=(const For& in) = default; + For(For&& in) = default; + For& operator=(For&& in) = default; + + For(const std::shared_ptr& indPtr, + Expr expr); + + For(const IndexClass* indPtr, + Expr expr); + + + inline void operator()(size_t mlast, ExtType last) const; + inline void operator()(size_t mlast = 0) const; + + auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType; + + }; + + template + size_t exceptMax(size_t max) { return max; } + + template <> + size_t exceptMax<1>(size_t max) { return 1; } + +} // namespace MultiArrayHelper + +/* ========================= * + * --- TEMPLATE CODE --- * + * ========================= */ + +#include + +namespace MultiArrayHelper +{ + + template + For::For(const std::shared_ptr& indPtr, + Expr expr) : + mIndPtr(indPtr.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mExpr(expr), + mExt(expr.rootSteps( reinterpret_cast( mIndPtr.get() ))) + { + assert(mIndPtr != nullptr); + //VCHECK(mIndPtr->id()); + //VCHECK(mIndPtr->max()); + } + + template + For::For(const IndexClass* indPtr, + Expr expr) : + mIndPtr(indPtr), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), + mExpr(std::forward( expr )), + mExt(expr.rootSteps( reinterpret_cast( mIndPtr ) )) + { + assert(mIndPtr != nullptr); + //VCHECK(mIndPtr->id()); + //VCHECK(mIndPtr->max()); + } + + template + inline void For::operator()(size_t mlast, + ExtType last) const + { + typedef typename IndexClass::RangeType RangeType; + for(size_t pos = 0u; pos != ForBound::template bound(mMax); ++pos){ + //for(size_t pos = mSPos; pos != mMax; ++pos){ + const size_t mnpos = PosForward::value(mlast, mMax, pos); + const ExtType npos = last + mExt*pos; + mExpr(mnpos, npos); + } + } + + template + inline void For::operator()(size_t mlast) const + { + typedef typename IndexClass::RangeType RangeType; + const ExtType last; + for(size_t pos = 0u; pos != ForBound::template bound(mMax); ++pos){ + //for(size_t pos = mSPos; pos != mMax; ++pos){ + const size_t mnpos = PosForward::value(mlast, mMax, pos); + const ExtType npos = last + mExt*pos; + mExpr(mnpos, npos); + } + } + + template + auto For::rootSteps(std::intptr_t iPtrNum) const + -> ExtType + { + return mExpr.rootSteps(iPtrNum); + } + + +} // namespace MultiArrayHelper + +#endif diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 0000000..4de9551 --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,11 @@ + +set(libmultiarray_a_SOURCES + ${CMAKE_SOURCE_DIR}/src/lib/ranges/range_base.cc + ${CMAKE_SOURCE_DIR}/src/lib/ranges/index_info.cc + #${CMAKE_SOURCE_DIR}/src/lib/operation_utils.cc + ) + +add_library(multiarray STATIC ${libmultiarray_a_SOURCES}) +install(TARGETS multiarray + ARCHIVE DESTINATION ${INSTALL_PATH}/lib + LIBRARY DESTINATION ${INSTALL_PATH}/lib) diff --git a/src/ranges/index_info.cc b/src/lib/ranges/index_info.cc similarity index 96% rename from src/ranges/index_info.cc rename to src/lib/ranges/index_info.cc index eaffcc4..f4f6220 100644 --- a/src/ranges/index_info.cc +++ b/src/lib/ranges/index_info.cc @@ -1,6 +1,6 @@ -#include "index_info.h" -#include "range_base.h" +#include "ranges/index_info.h" +#include "ranges/range_base.h" namespace MultiArrayTools { diff --git a/src/ranges/range_base.cc b/src/lib/ranges/range_base.cc similarity index 94% rename from src/ranges/range_base.cc rename to src/lib/ranges/range_base.cc index 07e6289..5df5738 100644 --- a/src/ranges/range_base.cc +++ b/src/lib/ranges/range_base.cc @@ -1,5 +1,5 @@ -#include "range_base.h" +#include "ranges/range_base.h" namespace MultiArrayTools { diff --git a/src/operation_utils.cc b/src/operation_utils.cc deleted file mode 100644 index d70ceb6..0000000 --- a/src/operation_utils.cc +++ /dev/null @@ -1,176 +0,0 @@ - -#include "operation_utils.h" -#include "ranges/range_base.h" - -namespace MultiArrayTools -{ - - namespace - { - using namespace MultiArrayHelper; - } - - void seekIndexInst(std::shared_ptr i, std::vector >& ivec) - { - std::cout << __func__ << ":" << std::endl; - for(size_t inum = 0; inum != i->rangePtr()->dim(); ++inum){ - std::cout << i->getPtrNum() << std::endl; - auto ii = i->getPtr(inum); - if(ii->type() == IndexType::MULTI or - ii->type() == IndexType::CONT){ - seekIndexInst(ii, ivec); - } - ivec.push_back(ii); - } - std::cout << std::endl; - } - - void seekIndexInst(const IndexInfo* i, std::vector& ivec) - { - std::cout << __func__ << ":" << std::endl; - for(size_t inum = 0; inum != i->dim(); ++inum){ - std::cout << i->getPtrNum() << std::endl; - auto ii = i->getPtr(inum); - if(ii->type() == IndexType::MULTI or - ii->type() == IndexType::CONT){ - seekIndexInst(ii, ivec); - } - ivec.push_back(ii); - } - std::cout << std::endl; - } - - BTSS getBlockType(std::shared_ptr i, - std::shared_ptr j, - bool first, size_t higherStepSize) - { - // returning BlockType and step size is redundant (change in the future) - // stepSize == 0 => VALUE - // stepSize == 1 => BLOCK - // stepSize > 1 => SPLIT :) - BTSS out(BlockType::VALUE, 0); - size_t lastNum = i->rangePtr()->dim(); - - for(size_t inum = 0; inum != lastNum; ++inum){ - auto ii = i->getPtr(inum); - if(ii->getPtrNum() == j->getPtrNum()){ - - if(inum == lastNum - 1 and first){ - out = BTSS(BlockType::BLOCK, 1); - } - else { - first = false; - out = BTSS(BlockType::SPLIT, i->getStepSize(inum) * higherStepSize + out.second); - } - continue; - } - - if(ii->type() == IndexType::MULTI or - ii->type() == IndexType::CONT){ - - BTSS tmp = getBlockType(ii, j, inum == lastNum - 1, i->getStepSize(inum) * higherStepSize); - if(tmp.first != BlockType::VALUE){ - out = tmp; - } - } - } - return out; - } - - BTSS getBlockType(const IndexInfo* i, - const IndexInfo* j, - bool first, size_t higherStepSize) - { - // returning BlockType and step size is redundant (change in the future) - // stepSize == 0 => VALUE - // stepSize == 1 => BLOCK - // stepSize > 1 => SPLIT :) - BTSS out(BlockType::VALUE, 0); - size_t lastNum = i->dim(); - - for(size_t inum = 0; inum != lastNum; ++inum){ - auto ii = i->getPtr(inum); - if(ii->getPtrNum() == j->getPtrNum()){ - - if(inum == lastNum - 1 and first){ - out = BTSS(BlockType::BLOCK, 1); - } - else { - first = false; - out = BTSS(BlockType::SPLIT, i->getStepSize(inum) * higherStepSize + out.second); - } - continue; - } - - if(ii->type() == IndexType::MULTI or - ii->type() == IndexType::CONT){ - - BTSS tmp = getBlockType(ii, j, inum == lastNum - 1, i->getStepSize(inum) * higherStepSize); - if(tmp.first != BlockType::VALUE){ - out = tmp; - } - } - } - return out; - } - - size_t getBTNum(const std::vector& mp, BlockType bt) - { - size_t out = 0; - for(auto& xx: mp){ - if(xx.first == bt){ - ++out; - } - } - return out; - } - - void minimizeAppearanceOfType(std::map, std::vector >& mp, - BlockType bt) - { - size_t minNum = getBTNum( mp.begin()->second, bt ); - for(auto& mm: mp){ - size_t tmp = getBTNum( mm.second, bt ); - if(tmp < minNum){ - minNum = tmp; - } - } - - for(auto mit = mp.begin(); mit != mp.end(); ){ - size_t tmp = getBTNum( mit->second, bt ); - if(tmp > minNum){ - mit = mp.erase(mit); - } - else { - ++mit; - } - } - - } - - void minimizeAppearanceOfType(std::map >& mp, - BlockType bt) - { - size_t minNum = getBTNum( mp.begin()->second, bt ); - for(auto& mm: mp){ - size_t tmp = getBTNum( mm.second, bt ); - if(tmp < minNum){ - minNum = tmp; - } - } - - for(auto mit = mp.begin(); mit != mp.end(); ){ - size_t tmp = getBTNum( mit->second, bt ); - if(tmp > minNum){ - mit = mp.erase(mit); - } - else { - ++mit; - } - } - - } - - - -} // end namespace MultiArrayTools diff --git a/src/operation_utils.h b/src/operation_utils.h deleted file mode 100644 index ee1d54e..0000000 --- a/src/operation_utils.h +++ /dev/null @@ -1,52 +0,0 @@ - -#ifndef __operation_utils_h__ -#define __operation_utils_h__ - -#include -#include -#include -#include - -#include "block/block.h" -#include "ranges/vindex_base.h" - -#include "ranges/index_info.h" - -namespace MultiArrayTools -{ - - namespace - { - using namespace MultiArrayHelper; - } - - // - typedef std::pair BTSS; - - - void seekIndexInst(std::shared_ptr i, std::vector >& ivec); - - void seekIndexInst(const IndexInfo* i, std::vector& ivec); - - BTSS getBlockType(std::shared_ptr i, - std::shared_ptr j, - bool first, size_t higherStepSize = 1); - - BTSS getBlockType(const IndexInfo* i, - const IndexInfo* j, - bool first, size_t higherStepSize = 1); - - - size_t getBTNum(const std::vector& mp, BlockType bt); - - void minimizeAppearanceOfType(std::map, std::vector >& mp, - BlockType bt); - - void minimizeAppearanceOfType(std::map >& mp, - BlockType bt); - - - -} // end namespace MultiArrayTools - -#endif diff --git a/src/ranges/tests/index_unit_test.cc~ b/src/ranges/tests/index_unit_test.cc~ deleted file mode 100644 index 34a3a8b..0000000 --- a/src/ranges/tests/index_unit_test.cc~ +++ /dev/null @@ -1,216 +0,0 @@ -// -*- C++ -*- - -#include -#include "gtest/gtest.h" -#include - -#include "rheader.h" - -//#include "multi_array_header.h" - -namespace MAT = MultiArrayTools; - -namespace { - - using namespace MAT; - - template - void swapFactory(std::shared_ptr& fptr, std::initializer_list ilist) - { - std::vector tmp = ilist; - auto nptr = std::make_shared( tmp ); - fptr = nptr; - } - - template - void swapMFactory(std::shared_ptr& fptr, const Rs&... rs) - { - auto nptr = std::make_shared( rs... ); - fptr = nptr; - } - - template - auto mkt(Ts&&... ts) -> decltype(std::make_tuple(ts...)) - { - return std::make_tuple(ts...); - } - - class IndexTest : public ::testing::Test - { - protected: - - typedef SingleRangeFactory SRF; - typedef SRF::oType SRange; - - typedef MultiRangeFactory M3RF; - typedef M3RF::oType M3Range; - - typedef MultiRangeFactory MasterRF; - typedef MasterRF::oType MasterRange; - - typedef ContainerRangeFactory CRF; - typedef CRF::oType CRange; - - IndexTest() - { - swapFactory(rfbptr, { 'e', 'b', 'n' } ); - sr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); - - swapFactory(rfbptr, { 'x', 'y', 'l', 'f' } ); - sr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); - - swapFactory(rfbptr, { 'a', 'b' } ); - std::shared_ptr temp1 = std::dynamic_pointer_cast( rfbptr->create() ); - swapFactory(rfbptr, { '1' } ); - std::shared_ptr temp2 = std::dynamic_pointer_cast( rfbptr->create() ); - swapFactory(rfbptr, { '0', '7' } ); - std::shared_ptr temp3 = std::dynamic_pointer_cast( rfbptr->create() ); - - swapMFactory(rfbptr, temp1, temp2, temp3 ); - m3rptr = std::dynamic_pointer_cast( rfbptr->create() ); - - swapMFactory(rfbptr, sr1ptr, m3rptr, sr2ptr); - mstrptr = std::dynamic_pointer_cast( rfbptr->create() ); - - swapMFactory(rfbptr, m3rptr, sr2ptr); - cr1ptr = std::dynamic_pointer_cast( rfbptr->create() ); - - swapMFactory(rfbptr, m3rptr, sr1ptr); - cr2ptr = std::dynamic_pointer_cast( rfbptr->create() ); - } - - std::shared_ptr rfbptr; - std::shared_ptr sr1ptr; - std::shared_ptr sr2ptr; - std::shared_ptr m3rptr; - std::shared_ptr mstrptr; - std::shared_ptr cr1ptr; - std::shared_ptr cr2ptr; - }; - - TEST_F(IndexTest, SingleIndex_SimpleCall) - { - auto si = sr1ptr->begin(); - EXPECT_EQ(si.max(), 3u); - EXPECT_EQ(si.pos(), 0u); - EXPECT_EQ(si.first(), true); - EXPECT_EQ(si.last(), false); - EXPECT_EQ(si.meta(), 'e'); - si.at('n'); - EXPECT_EQ(si.pos(), si.max()-1); - EXPECT_EQ(si.first(), false); - EXPECT_EQ(si.last(), true); - si = 1; - EXPECT_EQ(si.meta(), 'b'); - ++si; - EXPECT_EQ(si.meta(), 'n'); - auto si2 = sr1ptr->end(); - --si2; - EXPECT_EQ(si == si2, true); - EXPECT_EQ(si != si2, false); - auto si3 = sr2ptr->end(); - --si3; - EXPECT_EQ(si == si3, false); - EXPECT_EQ(si != si3, true); - } - - TEST_F(IndexTest, MultiIndex_SimpleCall) - { - auto mi = m3rptr->begin(); - EXPECT_EQ(mi.max(), 4u); - EXPECT_EQ(mi.pos(), 0u); - EXPECT_EQ(mi.first(), true); - EXPECT_EQ(mi.last(), false); - EXPECT_EQ(mi.meta() == mkt('a','1','0'), true); - mi.at( mkt('b','1','7') ); - EXPECT_EQ(mi.pos(), mi.max()-1); - EXPECT_EQ(mi.first(), false); - EXPECT_EQ(mi.last(), true); - mi = 1; - EXPECT_EQ(mi.meta() == mkt('a','1','7'), true); - ++mi; - EXPECT_EQ(mi.meta() == mkt('b','1','0'), true); - ++mi; - auto mi2 = m3rptr->end(); - --mi2; - EXPECT_EQ(mi == mi2, true); - EXPECT_EQ(mi != mi2, false); - --mi2; - EXPECT_EQ(mi == mi2, false); - EXPECT_EQ(mi != mi2, true); - auto si = sr1ptr->begin(); - EXPECT_EQ(si == mi, false); - EXPECT_EQ(si != mi, true); - } - - TEST_F(IndexTest, MasterRange_Check) - { - EXPECT_EQ(mstrptr->size(), 48u); - EXPECT_EQ(mstrptr->template get<0>().size(), 3u); - EXPECT_EQ(mstrptr->template get<1>().size(), 4u); - EXPECT_EQ(mstrptr->template get<2>().size(), 4u); - EXPECT_EQ(mstrptr->dim(), 3); - EXPECT_EQ(mstrptr->template get<0>().dim(), 1u); - EXPECT_EQ(mstrptr->template get<1>().dim(), 3u); - - auto mi = mstrptr->begin(); - EXPECT_EQ(mi.meta() == mkt( 'e' , mkt('a', '1', '0') , 'x' ), true); - mi = mi.max()-1; - EXPECT_EQ(mi.meta() == mkt( 'n' , mkt('b', '1', '7') , 'f' ), true); - mi.template down<1>(); - EXPECT_EQ(mi.meta() == mkt( 'n' , mkt('b', '1', '0') , 'f' ), true); - mi.template down<0>(); - EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '0') , 'f' ), true); - mi.template down<2>(); - EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '0') , 'l' ), true); - mi.template up<1>(); - EXPECT_EQ(mi.meta() == mkt( 'b' , mkt('b', '1', '7') , 'l' ), true); - - auto& subI = mi.template get<0>(); - EXPECT_EQ(subI.meta(), 'b'); - mi.template up<0>(); - EXPECT_EQ(subI.meta(), 'n'); - auto& subI2 = mi.template get<1>(); - EXPECT_EQ(subI2.meta() == mkt('b', '1', '7'), true); - mi.template down<1>(); - EXPECT_EQ(subI2.meta() == mkt('b', '1', '0'), true); - } - - TEST_F(IndexTest, ContainerRange_Check) - { - EXPECT_EQ(cr1ptr->size(), 16u); - EXPECT_EQ(cr2ptr->size(), 12u); - - auto mi = mstrptr->begin(); - auto ci1 = cr1ptr->begin(); - auto ci2 = cr2ptr->begin(); - - EXPECT_EQ(ci1.max(), 16u); - EXPECT_EQ(ci2.max(), 12u); - - ci1(mi.template getPtr<1>(), mi.template getPtr<2>()); - ci2(mi.template getPtr<1>(), mi.template getPtr<0>()); - - EXPECT_EQ(ci1.pos(), 0u); - EXPECT_EQ(ci2.pos(), 0u); - ++mi; - EXPECT_EQ(ci1().pos(), 1u); - EXPECT_EQ(ci2().pos(), 0u); - mi.template up<1>(); - EXPECT_EQ(ci1().pos(), 5u); - EXPECT_EQ(ci2().pos(), 3u); - mi.template up<0>(); - EXPECT_EQ(ci1().pos(), 5u); - EXPECT_EQ(ci2().pos(), 4u); - mi = mi.max()-1; - EXPECT_EQ(ci1().pos(), ci1.max()-1); - EXPECT_EQ(ci2().pos(), ci2.max()-1); - } - -} // end namespace - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100644 index 0000000..2ebab72 --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,21 @@ + +#add_executable(iutest /ranges/index_unit_test.cc ${INDEX_CC_FILES}) +add_executable(iutest ranges/index_unit_test.cc) +add_dependencies(iutest multiarray) +target_link_libraries(iutest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} multiarray) +add_test(NAME iutest COMMAND iutest) + +#add_executable(mautest src/tests/ma_unit_test.cc ${MA_CC_FILES}) +add_executable(mautest ma_unit_test.cc) +add_dependencies(mautest multiarray) +target_link_libraries(mautest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} multiarray) +add_test(NAME mautest COMMAND mautest) + +add_executable(oputest op_unit_test.cc) +add_dependencies(oputest multiarray) +target_link_libraries(oputest ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} multiarray) +add_test(NAME oputest COMMAND oputest) + +add_executable(opptest op_perf_test.cc) +add_dependencies(opptest multiarray) +target_link_libraries(opptest multiarray) diff --git a/src/ranges/tests/index_unit_test.cc b/src/tests/ranges/index_unit_test.cc similarity index 100% rename from src/ranges/tests/index_unit_test.cc rename to src/tests/ranges/index_unit_test.cc