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 "concept_check.h"
00027 #include "iterator_traits.h"
00028 #include "yat_assert.h"
00029
00030 #include <boost/concept_check.hpp>
00031 #include <boost/iterator/iterator_facade.hpp>
00032
00033 #include <cstddef>
00034 #include <iterator>
00035 #include <stdexcept>
00036 #include <utility>
00037
00038 namespace theplu {
00039 namespace yat {
00040 namespace utility {
00041
00060 template<typename Container, typename value, typename reference = value&>
00061 class Container2DIterator
00062 : public boost::iterator_facade<
00063 Container2DIterator<Container, value, reference>
00064 , value
00065 , std::random_access_iterator_tag
00066 , reference>
00067 {
00068 private:
00069 typedef Container2DIterator<Container, value, reference> self;
00070
00071 public:
00075 Container2DIterator(void)
00076 {
00077 BOOST_CONCEPT_ASSERT((Container2D<Container>));
00078 BOOST_CONCEPT_ASSERT((boost::Convertible<reference,value>));
00079 };
00080
00088 Container2DIterator(Container& container, size_t row, size_t column)
00089 : container_(&container), index_(row*container.columns()+column)
00090 {
00091 BOOST_CONCEPT_ASSERT((Container2D<Container>));
00092 BOOST_CONCEPT_ASSERT((boost::Convertible<reference,value>));
00093 }
00094
00095 private:
00096 friend class boost::iterator_core_access;
00097
00098 Container* container_;
00099 size_t index_;
00100
00101 void advance(int n) { index_+=n; }
00102
00103 void decrement(void) { --index_; }
00104
00105 int distance_to(const Container2DIterator& other) const
00106 { return other.index_ - index_; }
00107
00108 reference dereference(void) const
00109 {
00110 yat_assert<std::out_of_range>(index_ < this->size(),
00111 "Container2DIterator::dereference");
00112 return container_->operator()(row(index_), column(index_));
00113 }
00114
00115 bool equal(const Container2DIterator& other) const
00116 { return index_ == other.index_; }
00117
00118 void increment(void) { ++index_; }
00119
00120 size_t column(size_t i) const
00121 { return i % container_->columns(); }
00122 size_t row(size_t i) const
00123 { return static_cast<size_t>(i/container_->columns()); }
00124 size_t size() const
00125 { return container_->columns()*container_->rows(); }
00126
00127
00128
00129
00130
00131 };
00132
00133 }}}
00134
00135 #endif