some fixes -> first unit test compiles and runs successfully

This commit is contained in:
Christian Zimmermann 2017-02-17 18:10:03 +01:00
parent 5f02dcb177
commit 887547d5e1
18 changed files with 500 additions and 262 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
*/src/*~ */src/*~
*/src/*# */src/*#
build/
*/build/ */build/
*/install/ */install/

22
CMakeLists.txt Normal file
View file

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 2.8)
project(multi_array)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 --pedantic")
find_package( GTest REQUIRED )
if(GTest_FOUND)
include_directories(${GTEST_INCLUDE_DIRS})
else()
message(FATAL_ERROR "GTest not found")
endif()
include_directories(src)
add_executable(utest src/unit_test.cc)
target_link_libraries(utest ${GTEST_BOTH_LIBRARIES})
add_test(AllTests utest)
#install(TARGETS testm DESTINATION install)
set(CMAKE_INSTALL_PREFIX ..)

View file

@ -17,7 +17,7 @@ namespace MultiArrayTools
return mName; return mName;
} }
void name(const std::string& str) void IndefinitIndexBase::name(const std::string& str)
{ {
mName = str; mName = str;
} }
@ -86,64 +86,9 @@ namespace MultiArrayTools
* IndexBase * * IndexBase *
**************/ **************/
template <class Index>
Index& IndexBase<Index>::operator=(const Index& in)
{
setPos( evaluate(in) );
}
template <class Index>
Index& IndexBase<Index>::operator=(size_t pos)
{
setPos( pos );
return *this;
}
template <class Index>
Index& IndexBase<Index>::operator++()
{
setPos( ++mPos );
return *this;
}
template <class Index>
Index& IndexBase<Index>::operator--()
{
setPos( --mPos );
return *this;
}
template <class Index>
Index& IndexBase<Index>::operator+=(int n)
{
setPos( mPos += n );
return *this;
}
template <class Index>
Index& IndexBase<Index>::operator-=(int n)
{
setPos( mPos -= n );
return *this;
}
template <class Index>
bool IndexBase<Index>::operator==(const Index& i)
{
return mRange == i.mRange and mPos == i.mPos;
}
template <class Index>
bool IndexBase<Index>::operator!=(const Index& i)
{
return mRange != i.mRange or mPos != i.mPos;
}
template <class Index> template <class Index>
size_t IndexBase<Index>::max() const size_t IndexBase<Index>::max() const
{ {
return mRange->size(); return mRange->size();
} }
} }

View file

@ -17,7 +17,6 @@ namespace MultiArrayTools
class IndefinitIndexBase class IndefinitIndexBase
{ {
public: public:
virtual IndefinitIndexBase& operator=(const IndefinitIndexBase& in) = 0;
virtual IndefinitIndexBase& operator=(size_t pos) = 0; virtual IndefinitIndexBase& operator=(size_t pos) = 0;
virtual IndefinitIndexBase& operator++() = 0; virtual IndefinitIndexBase& operator++() = 0;
@ -25,8 +24,9 @@ namespace MultiArrayTools
virtual IndefinitIndexBase& operator+=(int n) = 0; virtual IndefinitIndexBase& operator+=(int n) = 0;
virtual IndefinitIndexBase& operator-=(int n) = 0; virtual IndefinitIndexBase& operator-=(int n) = 0;
virtual bool operator==(const IndefinitIndexBase& i) = 0; // Make this somehow better... !!!
virtual bool operator!=(const IndefinitIndexBase& i) = 0; //virtual bool operator==(const IndefinitIndexBase& i) = 0;
//virtual bool operator!=(const IndefinitIndexBase& i) = 0;
virtual size_t dim() const = 0; virtual size_t dim() const = 0;
virtual size_t pos() const; // = mPos; implement !!! virtual size_t pos() const; // = mPos; implement !!!
@ -35,7 +35,7 @@ namespace MultiArrayTools
virtual void name(const std::string& str); virtual void name(const std::string& str);
virtual void name(const Name& nm); virtual void name(const Name& nm);
MultiRangeType rangeType() const = 0; virtual MultiRangeType rangeType() const = 0;
virtual bool link(IndefinitIndexBase* toLink); virtual bool link(IndefinitIndexBase* toLink);
virtual void freeLinked(); virtual void freeLinked();
@ -61,18 +61,9 @@ namespace MultiArrayTools
class IndexBase : public IndefinitIndexBase class IndexBase : public IndefinitIndexBase
{ {
public: public:
virtual Index& operator=(const Index& in) override;
virtual Index& operator=(size_t pos) override; //virtual size_t pos() const override; // = mPos; implement !!!
virtual Index& operator++() override; virtual size_t max() const override;
virtual Index& operator--() override;
virtual Index& operator+=(int n) override;
virtual Index& operator-=(int n) override;
virtual bool operator==(const IndexBase& i) override;
virtual bool operator!=(const IndexBase& i) override;
virtual size_t pos() const override; // = mPos; implement !!!
protected: protected:

View file

@ -7,60 +7,56 @@ namespace MultiArrayTools
* MultiArray * * MultiArray *
*******************/ *******************/
namespace
{
template <typename... Ranges>
void giveNames(const std::string& name, /**/);
template <typename... Ranges>
void giveNames(const std::vector<std::string>& names, /**/);
}
/*!!!! giveNames(...) !!!!!*/
template <typename T, class Range> template <typename T, class Range>
MultiArray(const Range& range) : mRange(&range), mCont(mRange.size()) MultiArray<T,Range>::MultiArray(const Range& range) : mRange(new Range(range)), mCont(mRange.size())
{ {
mInit = true; mInit = true;
} }
template <typename T, class Range> template <typename T, class Range>
MultiArray(const Range& range, const std::vector<T>& vec) : mRange(&range), mCont(vec) MultiArray<T,Range>::MultiArray(const Range& range, const std::vector<T>& vec) : mRange(new Range(range)),
mCont(vec)
{ {
mInit = true; mInit = true;
if(mCont.size() > mRange.size()){ if(mCont.size() > mRange->size()){
mCont.erase(mCont.begin() + mRange.size(), mCont.end()); mCont.erase(mCont.begin() + mRange->size(), mCont.end());
} }
} }
template <typename T, class Range> template <typename T, class Range>
MultiArray(const Range& range, std::vector<T>&& vec) : mRange(&range), mCont(vec) MultiArray<T,Range>::MultiArray(const Range& range, std::vector<T>&& vec) : mRange(new Range(range)), mCont(vec)
{ {
mInit = true; mInit = true;
if(mCont.size() > mRange.size()){ if(mCont.size() > mRange->size()){
mCont.erase(mCont.begin() + mRange.size(), mCont.end()); mCont.erase(mCont.begin() + mRange->size(), mCont.end());
} }
} }
template <typename T, class Range> template <typename T, class Range>
T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) T& MultiArray<T,Range>::operator[](const typename Range::IndexType& i)
{ {
return mCont[ i.pos() ]; return mCont[ i.pos() ];
} }
template <typename T, class Range> template <typename T, class Range>
const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const const T& MultiArray<T,Range>::operator[](const typename Range::IndexType& i) const
{ {
return mCont[ i.pos() ]; return mCont[ i.pos() ];
} }
template <typename T, class Range> template <typename T, class Range>
template <class... NameTypes> template <class... NameTypes>
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const MultiArrayOperationBase<T,Range> MultiArray<T,Range>::operator()(const NameTypes&... str)
{ {
auto index = mRange->begin(); auto index = mRange->begin();
index.name(Name("master", str...)); index.name(Name("master", str...));
return MultiArrayOperation<T,Range>(*this, index); return MultiArrayOperationBase<T,Range>(*this, index);
}
template <typename T, class Range>
size_t MultiArray<T,Range>::size() const
{
return mRange->size();
} }
} }

View file

@ -6,6 +6,7 @@
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <memory>
#include "base_def.h" #include "base_def.h"
#include "multi_array_operation.h" #include "multi_array_operation.h"
@ -25,10 +26,12 @@ namespace MultiArrayTools
MultiArray(const Range& range, std::vector<T>&& vec); MultiArray(const Range& range, std::vector<T>&& vec);
template <class... NameTypes> template <class... NameTypes>
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const; MultiArrayOperationBase<T,Range> operator()(const NameTypes&... str);
T& operator()(const typename Range::indexType& i); T& operator[](const typename Range::IndexType& i);
const T& operator()(const typename Range::indexType& i) const; const T& operator[](const typename Range::IndexType& i) const;
size_t size() const;
private: private:
bool mInit = false; bool mInit = false;

14
src/multi_array_header.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef __multi_array_header_h__
#define __multi_array_header_h__
#include <cstdlib>
#include "base_def.h"
#include "range_base.h"
#include "index_base.h"
#include "single_range.h"
#include "multi_range.h"
#include "multi_array_operation.h"
#include "multi_array.h"
#endif

View file

@ -1,5 +1,5 @@
#include "mutli_array_operation.h" #include "multi_array_operation.h"
namespace MultiArrayTools namespace MultiArrayTools
{ {
@ -21,10 +21,10 @@ namespace MultiArrayTools
template <typename T, class Range> template <typename T, class Range>
template <class Operation, class... Ranges> template <class Operation, class... Ranges>
MultiArrayOperation<Operation> MultiArrayOperation<T,Range,Operation,Ranges...>
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs) MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
{ {
return MultiArrayOperationBase<T,Range>(op, secs); return MultiArrayOperation<T,Range,Operation,Ranges...>(op, secs...);
} }
template <typename T, class Range> template <typename T, class Range>
@ -48,44 +48,60 @@ namespace MultiArrayTools
template <typename T, class Range> template <typename T, class Range>
T& MultiArrayOperationBase<T,Range>::get() T& MultiArrayOperationBase<T,Range>::get()
{ {
return mArrayRef(*mIibPtr); return mArrayRef[*mIibPtr];
} }
template <typename T, class Range> template <typename T, class Range>
const T& MultiArrayOperationBase<T,Range>::get() const const T& MultiArrayOperationBase<T,Range>::get() const
{ {
return mArrayRef(*mIibPtr); return mArrayRef[*mIibPtr];
} }
/***************************** /*****************************
* MultiArrayOperation * * MultiArrayOperation *
*****************************/ *****************************/
template <class IndexTuple, size_t N> template <size_t N>
void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target) struct TupleIndicesLinker
{
template <class IndexTuple>
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{ {
std::get<N>(itp).linkTo(target); std::get<N>(itp).linkTo(target);
linkTupleIndicesTo<N-1>(itp, target); linkTupleIndicesTo<N-1>(itp, target);
} }
};
template <>
struct TupleIndicesLinker<0>
{
template <class IndexTuple> template <class IndexTuple>
void linkTupleIndicesTo<0>(IndexTuple& itp, IndefinitIndexBase* target) static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{ {
std::get<0>(itp).linkTo(target); std::get<0>(itp).linkTo(target);
} }
};
template <size_t N, class Operation, class Tuple, class... MBases> template <size_t N>
struct OperationCall
{
template <class Operation, class Tuple, class... MBases>
auto callOperation(Operation& op, Tuple& tp, MBases&... secs) auto callOperation(Operation& op, Tuple& tp, MBases&... secs)
-> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...)) -> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...))
{ {
return callOperation(op, tp, std::get<N-1>(tp), secs...); return callOperation(op, tp, std::get<N-1>(tp), secs...);
} }
};
template <>
struct OperationCall<0>
{
template <class Operation, class Tuple, class... MBases> template <class Operation, class Tuple, class... MBases>
auto callOperation<0>(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...)) auto callOperation(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...))
{ {
return op(secs.get()...); return op(secs.get()...);
} }
};
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
@ -96,21 +112,21 @@ namespace MultiArrayTools
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target) void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target)
{ {
mIibPtr->linkTo(target); OB::mIibPtr->linkTo(target);
linkTupleIndicesTo<sizeof...(Ranges)>(mSecs, target); TupleIndicesLinker<sizeof...(Ranges)>::linkTupleIndicesTo(mSecs, target);
} }
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
{ {
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs); mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs);
return mVal; return mVal;
} }
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
{ {
mVal = callOperation<sizeof...(Ranges)>(mOp, mSecs); mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs);
return mVal; return mVal;
} }

View file

@ -17,7 +17,7 @@ namespace MultiArrayTools
{ {
public: public:
MultiArrayOperation(MultiArray<T,Range>& ma, const IndefinitIndexBase& iib); MultiArrayOperationBase(MultiArray<T,Range>& ma, const IndefinitIndexBase& iib);
// execute AnyOperation // execute AnyOperation
// exception if range types are inconsitent with names // exception if range types are inconsitent with names
@ -26,19 +26,20 @@ namespace MultiArrayTools
template <class Operation, class... Ranges> template <class Operation, class... Ranges>
MultiArrayOperation<Operation> operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs); MultiArrayOperation<T,Range,Operation,Ranges...>
operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
template <class Range2> template <class Range2>
MultiArrayOperation<std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec);
virtual size_t argNum() const; virtual size_t argNum() const;
@ -61,6 +62,8 @@ namespace MultiArrayTools
{ {
public: public:
typedef MultiArrayOperationBase<T,Range> OB;
MultiArrayOperation(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs); MultiArrayOperation(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
virtual size_t argNum() const override; virtual size_t argNum() const override;
@ -80,6 +83,6 @@ namespace MultiArrayTools
} }
#include "multi_array_operation.h" #include "multi_array_operation.cc"
#endif #endif

View file

@ -1,5 +1,5 @@
#include "mutli_range.h" #include "multi_range.h"
namespace MultiArrayTools namespace MultiArrayTools
{ {
@ -9,8 +9,11 @@ namespace MultiArrayTools
namespace namespace
{ {
template <class MultiIndex, size_t N> template <size_t N>
IndefinitIndexBase& getIndex(MultiIndex& in, size_t n) struct IndexGetter
{
template <class MultiIndex>
static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
{ {
if(n == N){ if(n == N){
return in.getIndex<N>(); return in.getIndex<N>();
@ -19,26 +22,39 @@ namespace MultiArrayTools
return getIndex<N-1>(in, n); return getIndex<N-1>(in, n);
} }
} }
};
template <>
struct IndexGetter<0>
{
template <class MultiIndex> template <class MultiIndex>
IndefinitIndexBase& getIndex<MultiIndex,0>(MultiIndex& in, size_t n) static IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
{ {
return in.getIndex<0>(); return in.getIndex<0>();
} }
};
template <size_t N, class MultiIndex> template <size_t N>
size_t evaluate_x(const MultiIndex& index) struct Evaluation
{ {
const auto& subIndex = index.getIndex<N>();
return evaluate_x<N-1>(index) * subIndex.size() + subIndex.pos();
}
template <class MultiIndex> template <class MultiIndex>
size_t evaluate_x<0>(const MultiIndex& index) static size_t evaluate(const MultiIndex& index)
{ {
const auto& subIndex = index.getIndex<0>(); const auto& subIndex = index.getIndex<N>(0);
return Evaluation<N-1>::evaluate(index) * subIndex.size() + subIndex.pos();
}
};
template <>
struct Evaluation<0>
{
template <class MultiIndex>
static size_t evaluate(const MultiIndex& index)
{
const auto& subIndex = index.getIndex<0>(0);
return subIndex.pos(); return subIndex.pos();
} }
};
template <class MultiIndex> template <class MultiIndex>
inline void plus(MultiIndex& index, size_t digit, int num) inline void plus(MultiIndex& index, size_t digit, int num)
@ -48,54 +64,63 @@ namespace MultiArrayTools
size_t oor = si.outOfRange(); size_t oor = si.outOfRange();
if(oor and digit != MultiIndex::mult - 1){ if(oor and digit != MultiIndex::mult - 1){
plus(index, digit + 1, 1); plus(index, digit + 1, 1);
plus(index, digit, oor - max()); plus(index, digit, oor - si.max());
} }
} }
template <size_t N> template <size_t N>
void nameTuple(IndexPack& iPack, Name& name) struct TupleNamer
{
template <class IndexPack, class Name>
static void nameTuple(IndexPack& iPack, Name& name)
{ {
std::get<N>(iPack).name(name.get(N)); std::get<N>(iPack).name(name.get(N));
nameTuple<N-1>(iPack, name); nameTuple<N-1>(iPack, name);
} }
};
template <> template <>
void nameTuple<0>(IndexPack& iPack, Name& name) struct TupleNamer<0>
{
template <class IndexPack, class Name>
static void nameTuple(IndexPack& iPack, Name& name)
{ {
std::get<0>(iPack).name(name.get(0)); std::get<0>(iPack).name(name.get(0));
} }
};
} }
template <class... Indices>
MultiIndex<Indices...>::MultiIndex(Indices&&... inds) : mIPack(std::make_tuple(inds...)) {}
template <class... Indices> template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator++() MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{ {
setPos( pos() + 1 ); setPos( IIB::pos() + 1 );
plus(*this, 0, 1); plus(*this, 0, 1);
return *this; return *this;
} }
template <class... Indices> template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator--() MultiIndex<Indices...>& MultiIndex<Indices...>::operator--()
{ {
setPos( pos() - 1 ); setPos( IIB::pos() - 1 );
plus(*this, 0, -1); plus(*this, 0, -1);
return *this; return *this;
} }
template <class... Indices> template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator+=(int n) MultiIndex<Indices...>& MultiIndex<Indices...>::operator+=(int n)
{ {
setPos( pos() + n ); setPos( IIB::pos() + n );
plus(*this, 0, n); plus(*this, 0, n);
return *this; return *this;
} }
template <class... Indices> template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator-=(int n) MultiIndex<Indices...>& MultiIndex<Indices...>::operator-=(int n)
{ {
setPos( pos() - n ); setPos( IIB::pos() - n );
plus(*this, 0, 0-n); plus(*this, 0, 0-n);
return *this; return *this;
} }
@ -103,7 +128,7 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const size_t MultiIndex<Indices...>::evaluate(const MultiIndex<Indices...>& in) const
{ {
return evaluate_x<sizeof...(Indices)-1>(in); return Evaluation<sizeof...(Indices)-1>::evaluate(in);
} }
template <class... Indices> template <class... Indices>
@ -111,12 +136,12 @@ namespace MultiArrayTools
{ {
name(nm.own()); name(nm.own());
if(nm.size() >= sizeof...(Indices)){ if(nm.size() >= sizeof...(Indices)){
nameTuple<sizeof...(Indices)-1>(mIPack, nm); TupleNamer<sizeof...(Indices)-1>::nameTuple(mIPack, nm);
} }
else { else {
Name nm2 = nm; Name nm2 = nm;
nm2.autoName(sizeof...(Indices)); nm2.autoName(sizeof...(Indices));
nameTuple<sizeof...(Indices)-1>(mIPack, nm); TupleNamer<sizeof...(Indices)-1>::nameTuple(mIPack, nm);
} }
} }
@ -124,7 +149,7 @@ namespace MultiArrayTools
size_t MultiIndex<Indices...>::dim() const size_t MultiIndex<Indices...>::dim() const
{ {
size_t res = 1; size_t res = 1;
for(size_t i = 0; i != sMult; ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
res *= getIndex(i).dim(); res *= getIndex(i).dim();
} }
return res; return res;
@ -133,20 +158,20 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink) bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
{ {
if(toLink->rangeType() != rangeType() and toLink->name() == name()){ if(toLink->rangeType() != IIB::rangeType() and toLink->name() == name()){
// throw !! // throw !!
} }
if(toLink->rangeType() == rangeType() and toLink->name() == name()){ if(toLink->rangeType() == IIB::rangeType() and toLink->name() == name()){
if(mLinked == toLink){ if(IIB::mLinked == toLink){
return true; // dont link twice the same return true; // dont link twice the same
} }
else if(mLinked == nullptr){ else if(IIB::mLinked == nullptr){
mLinked = toLink; IIB::mLinked = toLink;
return true; return true;
} }
else { else {
return mLinked->link(toLink); return IIB::mLinked->link(toLink);
} }
} }
else { else {
@ -154,43 +179,46 @@ namespace MultiArrayTools
} }
} }
template <class... Indices>
template <size_t N> template <size_t N>
auto& MultiIndex<Indices...>::getIndex() -> decltype(std::get<N>(mIPack)) auto MultiIndex<Indices...>::getIndex(size_t x) -> decltype(std::get<N>(MultiIndex<Indices...>::IndexPack()))
{
return std::get<N>(mIPack);
}
template <size_t N>
const auto& MultiIndex<Indices...>::getIndex() const -> decltype(std::get<N>(mIPack));
{ {
return std::get<N>(mIPack); return std::get<N>(mIPack);
} }
template <class... Indices> template <class... Indices>
IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) template <size_t N>
auto MultiIndex<Indices...>::getIndex(size_t x) const ->
decltype(std::get<N>(MultiIndex<Indices...>::IndexPack()))
{ {
if(n >= sMult){ return std::get<N>(mIPack);
// throw !!
}
MultiIndex<Indices...>* t = this;
return getIndex<sizeof...(Indices)>(*t, n);
} }
template <class... Indices> template <class... Indices>
const IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) const IndefinitIndexBase& MultiIndex<Indices...>::get(size_t n)
{ {
if(n >= sMult){ if(n >= sizeof...(Indices)){
// throw !! // throw !!
} }
MultiIndex<Indices...>* t = this; MultiIndex<Indices...>* t = this;
return getIndex<sizeof...(Indices)>(*t, n); return IndexGetter<sizeof...(Indices)>::getIndex(*t, n);
}
template <class... Indices>
const IndefinitIndexBase& MultiIndex<Indices...>::get(size_t n) const
{
if(n >= sizeof...(Indices)){
// throw !!
}
MultiIndex<Indices...>* t = this;
return IndexGetter<sizeof...(Indices)>::getIndex(*t, n);
} }
template <class... Indices> template <class... Indices>
bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink) bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink)
{ {
bool res = false; bool res = false;
for(size_t i = 0; i != sMult; ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
res |= getIndex(i).link(toLink); res |= getIndex(i).link(toLink);
} }
return res; return res;
@ -200,7 +228,7 @@ namespace MultiArrayTools
void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target) void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target)
{ {
target->link(this); target->link(this);
for(size_t i = 0; i != sMult; ++i){ for(size_t i = 0; i != sizeof...(Indices); ++i){
getIndex(i).linkTo(target); getIndex(i).linkTo(target);
} }
} }
@ -209,11 +237,29 @@ namespace MultiArrayTools
* MultiRange * * MultiRange *
******************/ ******************/
template <class... Ranges>
template <size_t N> template <size_t N>
auto MultiRange<Ranges...>::get() -> decltype( std::get<N>(mSpace) ) auto MultiRange<Ranges...>::get() -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) )
{ {
return std::get<N>(mSpace); return std::get<N>(mSpace);
} }
template <class... Ranges>
template <size_t N>
auto MultiRange<Ranges...>::get() const -> decltype( std::get<N>(MultiRange<Ranges...>::SpaceType()) )
{
return std::get<N>(mSpace);
}
template <class... Ranges>
MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::begin() const
{
return MultiIndex<typename Ranges::IndexType...>(/*!!!!!!*/);
}
template <class... Ranges>
MultiIndex<typename Ranges::IndexType...> MultiRange<Ranges...>::end() const
{
return MultiIndex<typename Ranges::IndexType...>(/*!!!!!!*/);
}
} }

View file

@ -20,8 +20,10 @@ namespace MultiArrayTools
DEFAULT_MEMBERS(MultiIndex); DEFAULT_MEMBERS(MultiIndex);
MultiIndex(Indices&&... inds);
typedef std::tuple<Indices...> IndexPack; typedef std::tuple<Indices...> IndexPack;
static size_t sMult = sizeof...(Indices); typedef IndefinitIndexBase IIB;
virtual MultiIndex& operator++() override; virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override; virtual MultiIndex& operator--() override;
@ -29,13 +31,13 @@ namespace MultiArrayTools
virtual MultiIndex& operator-=(int n) override; virtual MultiIndex& operator-=(int n) override;
template <size_t N> template <size_t N>
auto& getIndex() -> decltype(std::get<N>(mIPack)); auto getIndex(size_t x) -> decltype(std::get<N>(IndexPack()));
template <size_t N> template <size_t N>
const auto& getIndex() const -> decltype(std::get<N>(mIPack)); auto getIndex(size_t x) const -> decltype(std::get<N>(IndexPack()));
IndefinitIndexBase& getIndex(size_t n); IndefinitIndexBase& get(size_t n);
const IndefinitIndexBase& getIndex(size_t n) const; const IndefinitIndexBase& get(size_t n) const;
virtual void name(const Name& nm) override; virtual void name(const Name& nm) override;
@ -54,18 +56,27 @@ namespace MultiArrayTools
}; };
template <class... Ranges> template <class... Ranges>
class MultiRange : public RangeBase<MultiIndex<typename Ranges::indexType...> > class MultiRange : public RangeBase<MultiIndex<typename Ranges::IndexType...> >
{ {
public: public:
typedef std::tuple<Ranges...> SpaceType;
DEFAULT_MEMBERS(MultiRange); DEFAULT_MEMBERS(MultiRange);
static size_t dim = sizeof...(Ranges); static const size_t dim = sizeof...(Ranges);
template <size_t N> template <size_t N>
auto get() -> decltype( std::get<N>(mSpace) ); auto get() -> decltype( std::get<N>(SpaceType()) );
template <size_t N>
auto get() const -> decltype( std::get<N>(SpaceType()) );
virtual MultiIndex<typename Ranges::IndexType...> begin() const override;
virtual MultiIndex<typename Ranges::IndexType...> end() const override;
protected: protected:
std::tuple<Ranges...> mSpace; SpaceType mSpace;
}; };
} }

View file

@ -6,6 +6,7 @@ namespace MultiArrayTools
namespace namespace
{ {
/*
template <class... NameTypes> template <class... NameTypes>
void giveNames(std::vector<Name>& nvec, const Name& name1, const Name& name2, const NameTypes&... names) void giveNames(std::vector<Name>& nvec, const Name& name1, const Name& name2, const NameTypes&... names)
{ {
@ -16,7 +17,7 @@ namespace MultiArrayTools
void giveNames(std::vector<Name>& nvec, const Name& name) void giveNames(std::vector<Name>& nvec, const Name& name)
{ {
nvec.push_back(name); nvec.push_back(name);
} }*/
void giveNames(std::vector<Name>& nvec) void giveNames(std::vector<Name>& nvec)
{ {
@ -48,9 +49,14 @@ namespace MultiArrayTools
mSub.resize(newSize); mSub.resize(newSize);
if(oldSize < newSize){ if(oldSize < newSize){
for(size_t i = oldSize; i != newSize; ++i){ for(size_t i = oldSize; i != newSize; ++i){
mSub[i] = mMain + to_string( i ); mSub[i] = mMain + std::to_string( i );
} }
} }
} }
size_t Name::size() const
{
return mSub.size();
}
} }

View file

@ -23,6 +23,7 @@ namespace MultiArrayTools
const Name& get(size_t n) const; const Name& get(size_t n) const;
void autoName(size_t newSize); void autoName(size_t newSize);
size_t size() const;
private: private:
std::string mMain; std::string mMain;
@ -31,4 +32,6 @@ namespace MultiArrayTools
} }
#include "name.cc"
#endif #endif

View file

@ -7,7 +7,19 @@ namespace MultiArrayTools
* MultiRangeType * * MultiRangeType *
*********************/ *********************/
MultiRangeType& MultiRangeType::operator=(RangeType& type) MultiRangeType::MultiRangeType(const RangeType& type) : mType(type), mMultiType(nullptr) {}
MultiRangeType::MultiRangeType(const std::vector<MultiRangeType>& multiType) :
mType(RangeType::NIL),
mMultiType(new std::vector<MultiRangeType>(multiType)) {}
MultiRangeType::~MultiRangeType()
{
delete mMultiType;
}
MultiRangeType& MultiRangeType::operator=(const RangeType& type)
{ {
setType(type); setType(type);
return *this; return *this;
@ -31,7 +43,7 @@ namespace MultiArrayTools
bool MultiRangeType::multi() const bool MultiRangeType::multi() const
{ {
return mType != nullptr; return mMultiType != nullptr;
} }
bool MultiRangeType::operator==(const MultiRangeType& in) const bool MultiRangeType::operator==(const MultiRangeType& in) const
@ -79,6 +91,12 @@ namespace MultiArrayTools
return false; return false;
} }
template <class Index>
RangeBase<Index>* RangeBase<Index>::base()
{
return nullptr;
}
/********************* /*********************
* SubRangeBase * * SubRangeBase *
*********************/ *********************/

View file

@ -5,6 +5,8 @@
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <memory>
#include "base_def.h" #include "base_def.h"
namespace MultiArrayTools namespace MultiArrayTools
@ -13,10 +15,11 @@ namespace MultiArrayTools
enum class RangeType enum class RangeType
{ {
NIL = 0, NIL = 0,
SPACE = 1, ANY = 1,
MOMENTUM = 2, SPACE = 2,
LORENTZ = 3, MOMENTUM = 3,
SPIN = 4 LORENTZ = 4,
SPIN = 5
}; };
class MultiRangeType class MultiRangeType
@ -25,7 +28,12 @@ namespace MultiArrayTools
DEFAULT_MEMBERS(MultiRangeType); DEFAULT_MEMBERS(MultiRangeType);
MultiRangeType& operator=(RangeType& type); MultiRangeType(const RangeType& type);
MultiRangeType(const std::vector<MultiRangeType>& multiType);
~MultiRangeType();
MultiRangeType& operator=(const RangeType& type);
MultiRangeType& operator=(const std::vector<MultiRangeType>& multiType); MultiRangeType& operator=(const std::vector<MultiRangeType>& multiType);
MultiRangeType& operator[](size_t num); MultiRangeType& operator[](size_t num);
@ -51,9 +59,9 @@ namespace MultiArrayTools
typedef Index IndexType; typedef Index IndexType;
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual Index begin() = 0; virtual Index begin() const = 0;
virtual Index end() = 0; virtual Index end() const = 0;
virtual RangeBase<Index>* base() = 0; virtual RangeBase<Index>* base();
virtual bool isSubRange() const; virtual bool isSubRange() const;
protected: protected:
@ -61,11 +69,11 @@ namespace MultiArrayTools
}; };
template <class Range> //template <class Range>
auto cross(const Range& r1, const Range& r2) -> /**/; //auto cross(const Range& r1, const Range& r2) -> /**/;
template <class Range1, class Range2> //template <class Range1, class Range2>
auto cross(const Range1& r1, const Range2& r2) -> /**/; //auto cross(const Range1& r1, const Range2& r2) -> /**/;
template <class Index> template <class Index>
class SubRangeBase : public RangeBase<Index> class SubRangeBase : public RangeBase<Index>

View file

@ -7,6 +7,10 @@ namespace MultiArrayTools
* SingleRange * * SingleRange *
********************/ ********************/
template <typename U, RangeType TYPE>
SingleRange<U,TYPE>::SingleRange(const std::vector<U>& space) : RangeBase<SingleIndex<U,TYPE> >(),
mSpace(space) {}
template <typename U, RangeType TYPE> template <typename U, RangeType TYPE>
const U& SingleRange<U,TYPE>::get(size_t pos) const const U& SingleRange<U,TYPE>::get(size_t pos) const
{ {
@ -26,44 +30,122 @@ namespace MultiArrayTools
return cnt; return cnt;
} }
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
size_t SingleRange<U,TYPE>::size() const size_t SingleRange<U,TYPE>::size() const
{ {
return mSpace.size(); return mSpace.size();
} }
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE> SingleRange<U,TYPE>::begin() const
{
return SingleIndex<U,TYPE>(0);
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE> SingleRange<U,TYPE>::end() const
{
return SingleIndex<U,TYPE>(mSpace.size());
}
/****************** /******************
* SingleIndex * * SingleIndex *
******************/ ******************/
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
const U& SingleIndexBase<U,TYPE>::getMetaPos() const SingleIndex<U,TYPE>::SingleIndex(const U& upos, size_t disambig) : IndexBase<SingleIndex<U,TYPE> >()
{ {
return dynamic_cast<SingleRange*>( mRange )->get(mPos); IIB::setPos( dynamic_cast<SingleRange<U,TYPE>*>( IB::mRange )->get(upos) );
} }
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
size_t SingleIndexBase<U,TYPE>::dim() const SingleIndex<U,TYPE>::SingleIndex(size_t pos) : IndexBase<SingleIndex<U,TYPE> >()
{
IIB::setPos( pos );
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator=(size_t pos)
{
IIB::setPos( pos );
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator++()
{
IIB::setPos( IIB::pos() + 1 );
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator--()
{
IIB::setPos( IIB::pos() - 1 );
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator+=(int n)
{
IIB::setPos( IIB::pos() + n );
return *this;
}
template <typename U, RangeType TYPE>
SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator-=(int n)
{
IIB::setPos( IIB::pos() - n );
return *this;
}
template <typename U, RangeType TYPE>
bool SingleIndex<U,TYPE>::operator==(const SingleIndex<U,TYPE>& i)
{
return IB::mRange == i.mRange and IIB::pos() == i.mPos;
}
template <typename U, RangeType TYPE>
bool SingleIndex<U,TYPE>::operator!=(const SingleIndex<U,TYPE>& i)
{
return IB::mRange != i.mRange or IIB::pos() != i.mPos;
}
template <typename U, RangeType TYPE>
MultiRangeType SingleIndex<U,TYPE>::rangeType() const
{
return MultiRangeType(TYPE);
}
template <typename U, RangeType TYPE>
const U& SingleIndex<U,TYPE>::getMetaPos() const
{
return dynamic_cast<SingleRange<U,TYPE>*>( IB::mRange )->get(IIB::pos());
}
template <typename U, RangeType TYPE>
size_t SingleIndex<U,TYPE>::dim() const
{ {
return 1; return 1;
} }
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
size_t SingleIndexBase<TYPE>::evaluate(const Index& in) size_t SingleIndex<U,TYPE>::evaluate(const SingleIndex<U,TYPE>& in) const
{ {
return in.mPos; return in.pos();
} }
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
void SingleIndexBase<U,TYPE>::linkTo(IndefinitIndexBase* target) void SingleIndex<U,TYPE>::linkTo(IndefinitIndexBase* target)
{ {
target->link(this); target->link(this);
} }
template <typename U, IndexType TYPE> template <typename U, RangeType TYPE>
SingleIndex& SingleIndexBase<U,TYPE>::operator=(const U& upos) SingleIndex<U,TYPE>& SingleIndex<U,TYPE>::operator=(const U& upos)
{ {
setPos( dynamic_cast<SingleRange*>( mRange )->get(upos) ); IIB::setPos( dynamic_cast<SingleRange<U,TYPE>*>( IB::mRange )->get(upos) );
return *this;
} }
} }

View file

@ -18,16 +18,35 @@ namespace MultiArrayTools
{ {
public: public:
typedef IndexBase<SingleIndex<U,TYPE> > IB;
typedef IndefinitIndexBase IIB;
DEFAULT_MEMBERS(SingleIndex); DEFAULT_MEMBERS(SingleIndex);
// find better solution !!!
SingleIndex(const U& upos, size_t disambig);
SingleIndex(size_t pos);
virtual SingleIndex& operator=(const U& upos); virtual SingleIndex& operator=(const U& upos);
virtual SingleIndex& operator=(size_t pos) override;
virtual SingleIndex& operator++() override;
virtual SingleIndex& operator--() override;
virtual SingleIndex& operator+=(int n) override;
virtual SingleIndex& operator-=(int n) override;
virtual bool operator==(const SingleIndex& i);
virtual bool operator!=(const SingleIndex& i);
virtual MultiRangeType rangeType() const override;
virtual const U& getMetaPos() const; virtual const U& getMetaPos() const;
virtual size_t dim() const override; // = 1 virtual size_t dim() const override; // = 1
virtual void linkTo(IndefinitIndexBase* target) override; virtual void linkTo(IndefinitIndexBase* target) override;
protected: protected:
virtual size_t evaluate(const Index& in) const override; virtual size_t evaluate(const SingleIndex& in) const override;
}; };
template <typename U, RangeType TYPE> template <typename U, RangeType TYPE>
@ -36,11 +55,16 @@ namespace MultiArrayTools
public: public:
DEFAULT_MEMBERS(SingleRange); DEFAULT_MEMBERS(SingleRange);
SingleRange(const std::vector<U>& space);
virtual size_t size() const override; virtual size_t size() const override;
const U& get(size_t pos) const; const U& get(size_t pos) const;
size_t get(const U& metaPos) const; size_t get(const U& metaPos) const;
SingleIndex<U,TYPE> begin() const override;
SingleIndex<U,TYPE> end() const override;
protected: protected:
std::vector<U> mSpace; std::vector<U> mSpace;
}; };

49
src/unit_test.cc Normal file
View file

@ -0,0 +1,49 @@
// -*- C++ -*-
#include <cstdlib>
#include "gtest/gtest.h"
#include <iostream>
#include "multi_array_header.h"
namespace MAT = MultiArrayTools;
namespace {
class OneDimTest : public ::testing::Test
{
protected:
typedef MAT::SingleRange<char,MAT::RangeType::ANY> Range1dAny;
typedef MAT::MultiArray<int,Range1dAny> MultiArray1dAny;
OneDimTest() : r({'a','b','c','d','e'}), ma(r, {-5,6,2,1,9}) {}
//virtual void SetUp();
Range1dAny r;
MultiArray1dAny ma;
};
TEST_F(OneDimTest, CorrectExtensions)
{
EXPECT_EQ(ma.size(), 5);
}
TEST_F(OneDimTest, CorrectAssigned)
{
EXPECT_EQ(ma[0], -5);
EXPECT_EQ(ma[1], 6);
EXPECT_EQ(ma[2], 2);
EXPECT_EQ(ma[3], 1);
EXPECT_EQ(ma[4], 9);
}
} // end namespace
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}