00001 #ifndef _theplu_yat_utility_container2d_iterator_
00002 #define _theplu_yat_utility_container2d_iterator_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "iterator_traits.h"
00027 #include "yat_assert.h"
00028
00029 #include <boost/iterator/iterator_facade.hpp>
00030
00031 #include <cstddef>
00032 #include <iterator>
00033 #include <stdexcept>
00034 #include <utility>
00035
00036 namespace theplu {
00037 namespace yat {
00038 namespace utility {
00039
00048 template<typename Container, typename value, typename reference = value&>
00049 class Container2DIterator
00050 : public boost::iterator_facade<
00051 Container2DIterator<Container, value, reference>
00052 , value
00053 , std::random_access_iterator_tag
00054 , reference>
00055 {
00056 private:
00057 typedef Container2DIterator<Container, value, reference> self;
00058
00059 public:
00063 Container2DIterator(void) {};
00064
00072 Container2DIterator(Container& container, size_t row, size_t column)
00073 : container_(&container), index_(row*container.columns()+column) {}
00074
00075 private:
00076 friend class boost::iterator_core_access;
00077
00078 Container* container_;
00079 size_t index_;
00080
00081 void advance(int n) { index_+=n; }
00082
00083 void decrement(void) { --index_; }
00084
00085 int distance_to(const Container2DIterator& other) const
00086 { return other.index_ - index_; }
00087
00088 reference dereference(void) const
00089 {
00090 yat_assert<std::out_of_range>(index_ < this->size(),
00091 "Container2DIterator::dereference");
00092 return container_->operator()(row(index_), column(index_));
00093 }
00094
00095 bool equal(const Container2DIterator& other) const
00096 { return index_ == other.index_; }
00097
00098 void increment(void) { ++index_; }
00099
00100 size_t column(size_t i) const
00101 { return i % container_->columns(); }
00102 size_t row(size_t i) const
00103 { return static_cast<size_t>(i/container_->columns()); }
00104 size_t size() const
00105 { return container_->columns()*container_->rows(); }
00106
00107
00108
00109
00110
00111 };
00112
00113 }}}
00114
00115 #endif