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 #include "iterator_traits.h"
00026 #include "yat_assert.h"
00027
00028 #include <boost/iterator/iterator_facade.hpp>
00029
00030 #include <iterator>
00031 #include <stddef.h>
00032 #include <stdexcept>
00033 #include <utility>
00034
00035 namespace theplu {
00036 namespace yat {
00037 namespace utility {
00038
00047 template<typename Container, typename value, typename reference = value&>
00048 class Container2DIterator
00049 : public boost::iterator_facade<
00050 Container2DIterator<Container, value, reference>
00051 , value
00052 , std::random_access_iterator_tag
00053 , reference>
00054 {
00055 private:
00056 typedef Container2DIterator<Container, value, reference> self;
00057
00058 public:
00062 Container2DIterator(void) {};
00063
00071 Container2DIterator(Container& container, size_t row, size_t column)
00072 : container_(&container), index_(row*container.columns()+column) {}
00073
00074 private:
00075 friend class boost::iterator_core_access;
00076
00077 Container* container_;
00078 size_t index_;
00079
00080 void advance(int n) { index_+=n; }
00081
00082 void decrement(void) { --index_; }
00083
00084 int distance_to(const Container2DIterator& other) const
00085 { return other.index_ - index_; }
00086
00087 reference dereference(void) const
00088 {
00089 yat_assert<std::out_of_range>(index_ < this->size(),
00090 "Container2DIterator::dereference");
00091 return container_->operator()(row(index_), column(index_));
00092 }
00093
00094 bool equal(const Container2DIterator& other) const
00095 { return index_ == other.index_; }
00096
00097 void increment(void) { ++index_; }
00098
00099 size_t column(size_t i) const
00100 { return i % container_->columns(); }
00101 size_t row(size_t i) const
00102 { return static_cast<size_t>(i/container_->columns()); }
00103 size_t size() const
00104 { return container_->columns()*container_->rows(); }
00105
00106
00107
00108
00109
00110 };
00111
00112 }}}
00113
00114 #endif