PlayaBlockIteratorImpl.hpp
00001
00002
00003
00004
00005 #ifndef PLAYA_BLOCKITERATORIMPL_HPP
00006 #define PLAYA_BLOCKITERATORIMPL_HPP
00007
00008
00009 #include "PlayaBlockIteratorDecl.hpp"
00010 #include "PlayaVectorSpaceDecl.hpp"
00011 #include "PlayaExceptions.hpp"
00012
00013 namespace Playa
00014 {
00015
00016 template <class Scalar> inline
00017 bool BlockIterator<Scalar>
00018 ::operator==(const BlockIterator<Scalar>& other) const
00019 {
00020 if (debug())
00021 {
00022 Out::os() << "comparing: LHS=" << *this
00023 << ", RHS=" << other << std::endl;
00024 }
00025 if (this->atEnd_ && other.atEnd_) return true;
00026 if (this->atEnd_ != other.atEnd_) return false;
00027 if (this->index_.size() != other.index_.size()) return false;
00028
00029 for (unsigned int i=0; i<this->index_.size(); i++)
00030 {
00031 if (this->index_[i] != other.index_[i]) return false;
00032 }
00033
00034 return true;
00035 }
00036
00037 template <class Scalar> inline
00038 bool BlockIterator<Scalar>
00039 ::operator<(const BlockIterator<Scalar>& other) const
00040 {
00041 if (debug())
00042 {
00043 Out::os() << "comparing (<): LHS=" << *this
00044 << ", RHS=" << other << std::endl;
00045 }
00046 TEUCHOS_TEST_FOR_EXCEPTION(this->space() != other.space(),
00047 RuntimeError, "Attempt to compare block iterators attached to "
00048 "two different spaces");
00049
00050 if (!this->atEnd_ && other.atEnd_) return true;
00051 if (this->atEnd_ && !other.atEnd_) return false;
00052 if (this->atEnd_ && other.atEnd_) return false;
00053
00054 int d = std::min(this->index_.size(), other.index_.size());
00055
00056
00057 for (int i=0; i<d; i++)
00058 {
00059 if (this->index_[i] < other.index_[i]) return true;
00060 if (this->index_[i] > other.index_[i]) return false;
00061 }
00062
00063 return false;
00064 }
00065
00066
00067
00068 template <class Scalar> inline
00069 BlockIterator<Scalar> BlockIterator<Scalar>::operator++(int)
00070 {
00071 if (debug())
00072 {
00073 Out::os() << "iter++" << std::endl;
00074 }
00075 BlockIterator<Scalar> old = *this;
00076
00077 TEUCHOS_TEST_FOR_EXCEPTION(this->atEnd_, RuntimeError,
00078 "attempt to advance a BlockIterator beyond end");
00079
00080 int depth = this->index_.size();
00081 TEUCHOS_TEST_FOR_EXCEPTION(depth <= 0, RuntimeError,
00082 "empty index stack in BlockIterator");
00083
00084 atEnd_ = !advance(depth-1);
00085
00086 if (debug())
00087 {
00088 Out::os() << "old=" << old << ", new=" << *this << std::endl;
00089 }
00090 return old;
00091 }
00092
00093 template <class Scalar> inline
00094 bool BlockIterator<Scalar>::advance(int level)
00095 {
00096 if (level < 0) return false;
00097
00098 this->index_[level]++;
00099 std::deque<int> base = this->index_;
00100 base.pop_back();
00101
00102 if (this->index_[level] >= this->space().getBlock(base).numBlocks())
00103 {
00104 this->index_.pop_back();
00105 return this->advance(level-1);
00106 }
00107 else
00108 {
00109 goToStart(this->space().getBlock(*this), this->index_);
00110 }
00111 return true;
00112 }
00113
00114 template <class Scalar> inline
00115 void BlockIterator<Scalar>
00116 ::goToStart(const VectorSpace<Scalar>& space,
00117 std::deque<int>& pos) const
00118 {
00119 pos.push_back(0);
00120 if (space.isBlockSpace())
00121 {
00122 goToStart(space.getBlock(0), pos);
00123 }
00124 }
00125
00126
00127 template <class Scalar> inline
00128 const VectorSpace<Scalar>& BlockIterator<Scalar>::space() const
00129 {
00130 return *(this->space_);
00131 }
00132
00133
00134 template <class Scalar> inline
00135 BlockIterator<Scalar>::BlockIterator(
00136 const VectorSpace<Scalar>& space,
00137 bool atEnd
00138 )
00139 : space_(rcp(new VectorSpace<Scalar>(space))),
00140 index_(),
00141 atEnd_(atEnd)
00142 {
00143 if (!atEnd)
00144 {
00145 goToStart(space, index_);
00146 }
00147 }
00148
00149
00150 template <class Scalar> inline
00151 std::ostream& BlockIterator<Scalar>::print(std::ostream& os) const
00152 {
00153 os << "BlockIterator";
00154 if (this->atEnd_)
00155 {
00156 os << "[end]";
00157 }
00158 else
00159 {
00160 os << "[index={";
00161 for (unsigned int i=0; i<index_.size(); i++)
00162 {
00163 if (i>0U) os << ", ";
00164 os << index_[i];
00165 }
00166 os << "}]";
00167 }
00168 return os;
00169 }
00170
00171
00172
00173 }
00174
00175
00176
00177
00178
00179 #endif