#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Buffer/BfAccIter2.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVL_SBFACCITER2_HEADER #define RAVL_SBFACCITER2_HEADER 1 /////////////////////////////////////////////////// //! userlevel=Normal //! rcsid="$Id: BfAccIter2.hh,v 1.9 2002/04/29 18:02:49 craftit Exp $" //! file="Ravl/Core/Container/Buffer/BfAccIter2.hh" //! lib=RavlCore //! author="Charles Galambos" //! docentry="Ravl.Core.Arrays.Buffer" //! date="10/09/1998" #include "Ravl/RBfAcc.hh" #include "Ravl/SBfAcc.hh" namespace RavlN { //! userlevel=Advanced //: Iterate 2 buffers at the same time. template class BufferAccessIter2C { public: inline BufferAccessIter2C(); //: Default constructor. inline BufferAccessIter2C(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2) { First(buff,buff2); } inline BufferAccessIter2C(const BufferAccessC &buff,const BufferAccessC &buff2,SizeT size) { First(buff,buff2,size); } inline BufferAccessIter2C(const SizeBufferAccessC &buff,const SizeBufferAccessC &buff2) { First(buff,buff2); } inline BufferAccessIter2C(const SizeBufferAccessC &buff,const SizeBufferAccessC &buff2,UIntT off1,UIntT off2) { First(buff,buff2,off1,off2); } //: Constructor. // start from off1 in the first array and off2 in the second. inline BufferAccessIter2C(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2,const IndexRangeC & range) { First(buff,buff2,range); } //: Constructor. // Only iterate through 'range' in both buffers. inline BufferAccessIter2C(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2,UIntT off1,UIntT off2 = 0) { First(buff,buff2,off1,off2); } //: Constructor. // Iterate through buffers starting at the given offsets off1 and off2 from the begining of the ranges. inline bool First(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2); //: Goto first elements. inline bool First(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2,const IndexRangeC &rng); //: Goto first elements. inline bool First(const SizeBufferAccessC &buff,const SizeBufferAccessC &buff2); //: Goto first elements. inline bool First(const SizeBufferAccessC &buff,const SizeBufferAccessC &buff2,UIntT off1,UIntT off2); //: Goto first elements. inline bool First(const RangeBufferAccessC &buff,const RangeBufferAccessC &buff2,UIntT off1,UIntT off2 = 0); //: Goto first elements. inline bool First(const BufferAccessC &buff,const BufferAccessC &buff2,SizeT size); //: Goto first elements. inline bool First(const BufferAccessC &buff,const IndexRangeC &rng1,const BufferAccessC &buff2,const IndexRangeC &rng2); //: Goto first elements. inline bool IsElm() const { return at1 < endOfRow; } //: At valid element ? inline bool IsLast() const { return (at1+1) == endOfRow; } //: Test if we're at the last valid element in the range. // Note: This is slightly slower than IsElm(). inline operator bool() { return at1 < endOfRow; } //: At valid element ? inline void Next(); //: Goto next element. // Call ONLY if IsElm() is valid. inline void Next(int skip) { at1 += skip; at2 += skip; } //: Advance 'skip' elements. // Call ONLY if you know this will not go past the end of the array. void operator++(int) { Next(); } //: Goto next element. // Call ONLY if IsElm() is valid. inline Data1T &Data1() { return *at1; } //: Access data. inline const Data1T &Data1() const { return *at1; } //: Access data. inline Data2T &Data2() { return *at2; } //: Access data. inline const Data2T &Data2() const { return *at2; } //: Access data. inline void Invalidate(); //: Make IsElm() return false. protected: Data1T *at1; Data2T *at2; const Data1T *endOfRow; }; ////////////////////////////////////////////////////// template inline BufferAccessIter2C::BufferAccessIter2C() : at1(0), endOfRow(0) {} template inline bool BufferAccessIter2C::First(const BufferAccessC &buff1,const BufferAccessC &buff2,SizeT size) { if(size <= 0) { at1 = 0; endOfRow = 0; return false; } at1 = const_cast(buff1.ReferenceElm()); at2 = const_cast(buff2.ReferenceElm()); endOfRow = &(at1[size]); return true; } template inline bool BufferAccessIter2C::First(const BufferAccessC &buff1,const IndexRangeC &rng1,const BufferAccessC &buff2,const IndexRangeC &rng2) { if(rng1.Size() <= 0) { at1 = 0; endOfRow = 0; return false; } RavlAssert(rng1.Size() <= rng2.Size()); at1 = const_cast(&buff1[rng1.Min()]); at2 = const_cast(&buff2[rng2.Min()]); endOfRow = &(at1[rng1.Size()]); return true; } template inline bool BufferAccessIter2C::First(const RangeBufferAccessC &buff1,const RangeBufferAccessC &buff2) { if(buff1.Size() <= 0) { at1 = 0; endOfRow = 0; return false; } RavlAssert(buff1.Size() <= buff2.Size()); at1 = const_cast(&buff1[buff1.IMin()]); at2 = const_cast(&buff2[buff2.IMin()]); endOfRow = &(at1[buff1.Size()]); return true; } template inline bool BufferAccessIter2C::First(const SizeBufferAccessC &buff1,const SizeBufferAccessC &buff2) { if(buff1.Size() <= 0) { at1 = 0; endOfRow = 0; return false; } RavlAssert(buff1.Size() <= buff2.Size()); at1 = const_cast(buff1.ReferenceElm()); at2 = const_cast(buff2.ReferenceElm()); endOfRow = &(at1[buff1.Size()]); return true; } template inline bool BufferAccessIter2C::First(const SizeBufferAccessC &buff1,const SizeBufferAccessC &buff2,UIntT off1,UIntT off2) { if(buff1.Size() <= off1) { at1 = 0; endOfRow = 0; return false; } RavlAssert(buff2.Size() > off2); RavlAssert(((int) buff2.Size() - off2) >= ((int) buff1.Size() - off1)); at1 = const_cast(&buff1[off1]); at2 = const_cast(&buff2[off2]); endOfRow = &(at1[buff1.Size() - off1]); return true; } template inline bool BufferAccessIter2C::First(const RangeBufferAccessC &buff1,const RangeBufferAccessC &buff2,UIntT off1,UIntT off2) { if(buff1.Size() <= off1) { at1 = 0; endOfRow = 0; return false; } RavlAssert(buff2.Size() > off2); RavlAssert(((int) buff2.Size() - off2) >= ((int) buff1.Size() - off1)); at1 = const_cast(&buff1[buff1.IMin() + off1]); at2 = const_cast(&buff2[buff2.IMin() + off2]); endOfRow = &(at1[buff1.Size() - off1]); return true; } template inline bool BufferAccessIter2C::First(const RangeBufferAccessC &buff1,const RangeBufferAccessC &buff2,const IndexRangeC & range) { if(range.Size() <= 0) { at1 = 0; endOfRow = 0; return false; } RavlAssert(buff1.Range().Contains(range)); RavlAssert(buff2.Range().Contains(range)); at1 = const_cast(&buff1[range.Min()]); at2 = const_cast(&buff2[range.Min()]); endOfRow = &(at1[range.Size()]); return true; } template inline void BufferAccessIter2C::Next() { RavlAssert(at1 < endOfRow); at1++; at2++; } template inline void BufferAccessIter2C::Invalidate() { at1 = 0; endOfRow = 0; } } #endif