Mega Code Archive

 
Categories / C++ Tutorial / Data Types
 

SArray

/* The following code example is taken from the book  * "C++ Templates - The Complete Guide"  * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002  *  * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002.  * Permission to copy, use, modify, sell and distribute this software  * is granted provided this copyright notice appears in all copies.  * This software is provided "as is" without express or implied  * warranty, and with no claim as to its suitability for any purpose.  */ #include <stddef.h> #include <cassert> template<typename T> class SArray {   public:     // create array with initial size     explicit SArray (size_t s)      : storage(new T[s]), storage_size(s) {         init();     }     // copy constructor     SArray (SArray<T> const& orig)      : storage(new T[orig.size()]), storage_size(orig.size()) {         copy(orig);     }     // destructor: free memory     ~SArray() {         delete[] storage;     }     // assignment operator     SArray<T>& operator= (SArray<T> const& orig) {         if (&orig!=this) {             copy(orig);         }         return *this;     }     // return size     size_t size() const {         return storage_size;     }     // index operator for constants and variables     T operator[] (size_t idx) const {         return storage[idx];     }     T& operator[] (size_t idx) {         return storage[idx];     }   protected:     // init values with default constructor     void init() {         for (size_t idx = 0; idx<size(); ++idx) {             storage[idx] = T();         }     }     // copy values of another array     void copy (SArray<T> const& orig) {         assert(size()==orig.size());         for (size_t idx = 0; idx<size(); ++idx) {             storage[idx] = orig.storage[idx];         }     }   private:     T*     storage;       // storage of the elements     size_t storage_size;  // number of elements }; // include helper class traits template to select whether to refer to an // ''expression template node'' either ''by value'' or ''by reference.'' /* helper traits class to select how to refer to an ''expression template node''  * - in general: by reference  * - for scalars: by value  */ template <typename T> class A_Scalar; // primary template template <typename T> class A_Traits {   public:     typedef T const& ExprRef;     // type to refer to is constant reference }; // partial specialization for scalars template <typename T> class A_Traits<A_Scalar<T> > {   public:     typedef A_Scalar<T> ExprRef;  // type to refer to is ordinary value }; // class for objects that represent the addition of two operands template <typename T, typename OP1, typename OP2> class A_Add {   private:     typename A_Traits<OP1>::ExprRef op1;    // first operand     typename A_Traits<OP2>::ExprRef op2;    // second operand   public:     // constructor initializes references to operands     A_Add (OP1 const& a, OP2 const& b)      : op1(a), op2(b) {     }     // compute sum when value requested     T operator[] (size_t idx) const {         return op1[idx] + op2[idx];     }     // size is maximum size     size_t size() const {         assert (op1.size()==0 || op2.size()==0                 || op1.size()==op2.size());         return op1.size()!=0 ? op1.size() : op2.size();     } }; // class for objects that represent the multiplication of two operands template <typename T, typename OP1, typename OP2> class A_Mult {   private:     typename A_Traits<OP1>::ExprRef op1;    // first operand     typename A_Traits<OP2>::ExprRef op2;    // second operand   public:     // constructor initializes references to operands     A_Mult (OP1 const& a, OP2 const& b)      : op1(a), op2(b) {     }     // compute product when value requested     T operator[] (size_t idx) const {         return op1[idx] * op2[idx];     }     // size is maximum size     size_t size() const {         assert (op1.size()==0 || op2.size()==0                 || op1.size()==op2.size());         return op1.size()!=0 ? op1.size() : op2.size();     } }; int main() {     SArray<double> x(1000), y(1000);     //...     //x = 1.2*x + x*y; }