00001
00010
00011
00012
00013
00014 #ifndef ECL_CONTAINERS_STENCIL_STENCIL_HPP_
00015 #define ECL_CONTAINERS_STENCIL_STENCIL_HPP_
00016
00017
00018
00019
00020
00021 #include <cstddef>
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
00031
00032
00033 namespace ecl
00034 {
00035
00036
00037
00038
00071 template <typename Array>
00072 class ECL_PUBLIC Stencil
00073 {
00074 public:
00075
00076
00077
00078 typedef typename Array::value_type value_type;
00079
00080
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
00086
00087
00088
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
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
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 {
00244 b_iter = s.b_iter;
00245 e_iter = s.e_iter;
00246 }
00247 else
00248 {
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
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
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
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
00470
00476 size_type size() const
00477 { return e_iter-b_iter;}
00478
00479
00480
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
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 }
00527
00528 #endif