stencil.hpp
Go to the documentation of this file.
00001 
00010 /*****************************************************************************
00011  ** Ifdefs
00012  *****************************************************************************/
00013 
00014 #ifndef ECL_CONTAINERS_STENCIL_STENCIL_HPP_
00015 #define ECL_CONTAINERS_STENCIL_STENCIL_HPP_
00016 
00017 /*****************************************************************************
00018  ** Includes
00019  *****************************************************************************/
00020 
00021 #include <cstddef>  // size_t
00022 #include <ecl/config/macros.hpp>
00023 #include <ecl/exceptions/standard_exception.hpp>
00024 #include <ecl/concepts/containers.hpp>
00025 #include <ecl/concepts/streams.hpp>
00026 #include "../initialiser.hpp"
00027 #include "formatters.hpp"
00028 
00029 /*****************************************************************************
00030  ** Namespaces
00031  *****************************************************************************/
00032 
00033 namespace ecl
00034 {
00035 
00036 /*****************************************************************************
00037  ** Interface
00038  *****************************************************************************/
00071 template <typename Array>
00072 class ECL_PUBLIC Stencil
00073 {
00074 public:
00075   /*********************
00076    ** Typedefs
00077    **********************/
00078   typedef typename Array::value_type value_type; 
00079   //   Looks like I'm now needing to rely on the underlying storage iterator definitions
00080   //   Naturally, this means I can't do stencils of c arrays, but hey, thats dangerous anyway and we want to avoid that.
00081   typedef typename Array::iterator iterator; 
00082   typedef typename Array::const_iterator const_iterator; 
00083   typedef typename Array::reference reference; 
00084   typedef typename Array::const_reference const_reference; 
00085   // typedef typename Array::value_type*          iterator;   /**< @brief Uses the array's iterator type. **/
00086   // typedef const typename Array::value_type*    const_iterator;  /**< @brief Uses the array's constant iterator type. **/
00087   // typedef typename Array::value_type&          reference;  /**< @brief Uses the array's element reference type. **/
00088   // typedef const typename Array::value_type&    const_reference; /**< @brief Uses the array's element const reference type. **/
00089   typedef std::size_t size_type; 
00090   typedef std::ptrdiff_t difference_type;
00091   typedef std::reverse_iterator<iterator> reverse_iterator; 
00092   typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 
00093   typedef formatters::StencilFormatter<value_type,Array> Formatter;
00094 
00095   /*********************
00096    ** C&D's
00097    **********************/
00113   Stencil(Array& underlying_array, iterator begin_iter, iterator end_iter) ecl_assert_throw_decl(StandardException) :
00114   array(underlying_array),
00115   b_iter(begin_iter),
00116   e_iter(end_iter)
00117   {
00118     ecl_compile_time_concept_check(ContainerConcept<Array>);
00119     ecl_assert_throw((b_iter >= array.begin()) && (b_iter <= array.end()), StandardException(LOC, OutOfRangeError, "Begin iterator out of range."));
00120     ecl_assert_throw((e_iter >= array.begin()) && (e_iter <= array.end()), StandardException(LOC, OutOfRangeError, "End iterator out of range."));
00121   }
00122 
00138   Stencil(Array& underlying_array, const unsigned int& start_index = 0, const unsigned int &n = 0) ecl_assert_throw_decl(StandardException) :
00139   array(underlying_array),
00140   b_iter(array.begin()+start_index),
00141   e_iter(array.begin()+start_index+n)
00142   {
00143     ecl_compile_time_concept_check(ContainerConcept<Array>);
00144     ecl_assert_throw((b_iter >= array.begin()) && (b_iter <= array.end()), StandardException(LOC, OutOfRangeError, "Begin iterator out of range."));
00145     ecl_assert_throw((e_iter >= array.begin()) && (e_iter <= array.end()), StandardException(LOC, OutOfRangeError, "End iterator out of range."));
00146   }
00147 
00148   virtual ~Stencil()
00149   {};
00150 
00163   Stencil<Array> stencil(const unsigned int& start_index, const unsigned int& n) const ecl_assert_throw_decl(StandardException)
00164   {
00165     ecl_assert_throw( b_iter+start_index < array.end(), StandardException(LOC, OutOfRangeError, "Start index provided is larger than the underlying stencil size."));
00166     ecl_assert_throw( b_iter+start_index+n <= array.end(), StandardException(LOC, OutOfRangeError, "Finish index provided is larger than the underlying stencil size."));
00167     return Stencil<Array>(array,b_iter+start_index,b_iter+start_index+n);
00168   }
00169 
00181   void resettle(const unsigned int& start_index, const unsigned int& n) ecl_assert_throw_decl(StandardException)
00182   {
00183 
00184     b_iter = array.begin()+start_index;
00185     e_iter = array.begin()+start_index+n;
00186     ecl_assert_throw((b_iter >= array.begin()) && (b_iter <= array.end()), StandardException(LOC, OutOfRangeError, "Begin iterator out of range."));
00187     ecl_assert_throw((e_iter >= array.begin()) && (e_iter <= array.end()), StandardException(LOC, OutOfRangeError, "End iterator out of range."));
00188   }
00189 
00190   /*********************
00191    ** Assignment
00192    **********************/
00206   containers::BoundedListInitialiser<value_type,value_type*> operator<< (const value_type &value)
00207   {
00208     return containers::BoundedListInitialiser<value_type,iterator>(value, begin, size());
00209   }
00240   Stencil<Array>& operator=(const Stencil<Array> &s) ecl_assert_throw_decl(StandardException)
00241   {
00242     if ( &array == &(s.array) )
00243     { // resettle
00244       b_iter = s.b_iter;
00245       e_iter = s.e_iter;
00246     }
00247     else
00248     { // copy
00249       ecl_assert_throw( s.size() <= size(), StandardException(LOC, OutOfRangeError, "Stencil to be copied is larger than this stencil's size."));
00250       for ( unsigned int i = 0; i < s.size(); ++i )
00251       {
00252         *(b_iter+i) = *(s.b_iter+i);
00253       }
00254     }
00255     return *this;
00256   }
00257 
00258   /*********************
00259    ** Iterators
00260    **********************/
00266   iterator begin() ecl_assert_throw_decl(StandardException)
00267   {
00268     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00269     return b_iter;
00270   }
00276   const_iterator begin() const ecl_assert_throw_decl(StandardException)
00277   {
00278     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00279     return b_iter;
00280   }
00286   iterator end() ecl_assert_throw_decl(StandardException)
00287   {
00288     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00289     return e_iter;
00290   }
00296   const_iterator end() const ecl_assert_throw_decl(StandardException)
00297   {
00298     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00299     return e_iter;
00300   }
00306   reverse_iterator rbegin() ecl_assert_throw_decl(StandardException)
00307   {
00308     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00309     return reverse_iterator(end());
00310   }
00316   const_reverse_iterator rbegin() const ecl_assert_throw_decl(StandardException)
00317   {
00318     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00319     return const_reverse_iterator(end());
00320   }
00326   reverse_iterator rend() ecl_assert_throw_decl(StandardException)
00327   {
00328     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00329     return reverse_iterator(begin());
00330   }
00336   const_reverse_iterator rend() const ecl_assert_throw_decl(StandardException)
00337   {
00338     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00339     return const_reverse_iterator(begin());
00340   }
00341 
00342   /*********************
00343    ** Front/Back
00344    **********************/
00350   reference front() ecl_assert_throw_decl(StandardException)
00351   {
00352     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00353     return *b_iter;
00354   }
00360   const_reference front() const ecl_assert_throw_decl(StandardException)
00361   {
00362     ecl_assert_throw( b_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00363     return *b_iter;
00364   }
00370   reference back() ecl_assert_throw_decl(StandardException)
00371   {
00372     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00373     return *(e_iter-1);
00374   }
00380   const_reference back() const ecl_assert_throw_decl(StandardException)
00381   {
00382     ecl_assert_throw( e_iter <= array.end(), StandardException(LOC,OutOfRangeError));
00383     return *(e_iter-1);
00384   }
00385 
00386   /*********************
00387    ** Accessors
00388    **********************/
00398   reference operator[](size_type i) ecl_assert_throw_decl(StandardException)
00399   {
00400     ecl_assert_throw( b_iter+i >= array.begin(), StandardException(LOC,OutOfRangeError));
00401     ecl_assert_throw( b_iter+i <= array.end(), StandardException(LOC,OutOfRangeError));
00402     return *(b_iter+i);
00403   }
00415   const_reference operator[](size_type i) const ecl_assert_throw_decl(StandardException)
00416   {
00417     ecl_assert_throw( b_iter+i >= array.begin(), StandardException(LOC,OutOfRangeError));
00418     ecl_assert_throw( b_iter+i <= array.end(), StandardException(LOC,OutOfRangeError));
00419     return *(b_iter+i);
00420   }
00431   reference at(size_type i) throw(StandardException)
00432   {
00433     if ( b_iter+i <= array.begin() )
00434     {
00435       throw StandardException(LOC,OutOfRangeError);
00436     }
00437     if ( b_iter+i >= array.end() )
00438     {
00439       throw StandardException(LOC,OutOfRangeError);
00440     }
00441     return *(b_iter+i);
00442   }
00455   const_reference at(size_type i) const throw(StandardException)
00456   {
00457     if ( b_iter+i <= array.begin() )
00458     {
00459       throw StandardException(LOC,OutOfRangeError);
00460     }
00461     if ( b_iter+i >= array.end() )
00462     {
00463       throw StandardException(LOC,OutOfRangeError);
00464     }
00465     return *(b_iter+i);
00466   }
00467 
00468   /*********************
00469    ** Utilities
00470    **********************/
00476   size_type size() const
00477   { return e_iter-b_iter;}
00478 
00479   /*********************
00480    ** Streaming
00481    **********************/
00497   template <typename OutputStream, typename ArrayType>
00498   friend OutputStream& operator<<(OutputStream &ostream , const Stencil<ArrayType> &stencil);
00499 
00500 private:
00501   Array& array;
00502   iterator b_iter, e_iter;
00503 };
00504 
00505 /*****************************************************************************
00506  ** Implementation [Streaming]
00507  *****************************************************************************/
00508 
00509 template<typename OutputStream, typename ArrayType>
00510   OutputStream& operator<<(OutputStream &ostream, const Stencil<ArrayType> &stencil)
00511   {
00512 
00513     ecl_compile_time_concept_check (StreamConcept<OutputStream> );
00514 
00515     ostream << "[ ";
00516     for (std::size_t i = 0; i < stencil.size(); ++i)
00517     {
00518       ostream << stencil[i] << " ";
00519     }
00520     ostream << "]";
00521     ostream.flush();
00522 
00523     return ostream;
00524   }
00525 
00526 } // namespace ecl
00527 
00528 #endif /* ECL_CONTAINERS_STENCIL_STENCIL_HPP_ */


ecl_containers
Author(s): Daniel Stonier
autogenerated on Sun Oct 5 2014 23:35:46