0. //Array.cpp Array a(shape), b(shape), c(shape), d(shape); //Array.h Array(const vector shape) { long i, sum; sum=1; for (i=0; ishape).push_back(shape[i]); } this->size = sum; this->d = my_malloc(sum*sizeof(T)); } private: // The underlying complicated data structure T * d; vector shape; long size; 1. //Array.cpp b=1;c=2;d=3; //Array.h Array &operator=(T value) { for(long i=0; isize; i++) d[i] = value; return *this; } 2. //Array.cpp b=c; //Array.h Array &operator=(const Array &v) { for(long i=0; isize; i++) d[i] = v.d[i]; return *this; } 3. 1) //Array.cpp a = b + c + d; 2) //Array.h template Array &operator=(const Expression &rhs) { for(long i=0; isize; i++) d[i] = forEach(rhs, EvalLeaf1(i), OpCombine()); return *this; } 3) //ForEach.h // CLASS NAME // ForEach // forEach(Expr& e, FTag& f, CTag& c) //call this function //same as ForEach::apply // // Expr is the type of the expression tree. // FTag is the type of the leaf tag.(specifies the operation being applied) // CTag is the type of the combiner tag. // // ForEach::apply(Expr &e,FTag& f,CTag& c) is a function // that traverses the expression tree defined by e, applies the functor f // to each leaf and combines the results together using the combiner c. // The type of object returned is given by: // typename ForEach::Type_t // the function forEach(Expr& e,FTag& f,CTag& c) duplicates the action // of ForEach::apply 4) CreateLeaf.h (defines expression tree) template class Expression { public: // Type of the expression. typedef T Expression_t; // Construct from an expression. Expression(const T& expr) : expr_m(expr) { } // Accessor that returns the expression. const Expression_t& expression() const { return expr_m; } private: // Store the expression by value since it is a temporary produced // by operator functions. T expr_m; }; 5) Functors.h (functors define here, however....) // LeafFunctors are used by ForEach to apply operations to the leaves of the // expression tree. Typical functors are evaluators, counters, etc. struct EvalLeaf1 { int i1_m; inline EvalLeaf1(int i1) : i1_m(i1) { } inline int val1() const { return i1_m; } }; ******BUT Array.h specializes EvalLeaf1 function as following******* //----------------------------------------------------------------------------- // Specialization of LeafFunctor class for applying the EvalLeaf1 // tag to a Array. The apply method simply returns the array // evaluated at the point. //----------------------------------------------------------------------------- template struct LeafFunctor, EvalLeaf1> { typedef T Type_t; static Type_t apply(const Array &a, const EvalLeaf1 &f) { return a[f.val1()]; } }; 6)Combiners.h (defines combiner tag) //----------------------------------------------------------------------------- // // CLASS NAME // OpCombine // // DESCRIPTION // A combiner that uses the operations in the expression tree. // //----------------------------------------------------------------------------- struct OpCombine { PETE_EMPTY_CONSTRUCTORS(OpCombine) }; template struct Combine1 { typedef typename UnaryReturn::Type_t Type_t; inline static Type_t combine(A a, Op op, OpCombine) { return op(a); } }; template struct Combine2 { typedef typename BinaryReturn::Type_t Type_t; inline static Type_t combine(A a, B b, Op op, OpCombine) { return op(a, b); } }; template struct Combine3 { typedef typename TrinaryReturn::Type_t Type_t; inline static Type_t combine(A a, B b, C c, Op op, OpCombine) { return op(a, b, c); } }; 4.user defined Expression <> tree example Array d; const Expression, Reference > > &expr1 = b + c; d = expr1; cout << d << endl; int num = forEach(expr1, CountLeaf(), SumCombine()); cout << num << endl; const Expression, BinaryNode, Reference > > > &expr2 = b + 3 * c; num = forEach(expr2, CountLeaf(), SumCombine()); cout << num << endl; const Expression, BinaryNode, Reference > > > &expr3 = b + c * d; num = forEach(expr3, CountLeaf(), SumCombine()); cout << num << endl;