#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Buffer/SBfAcc.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_SBFACC_HEADER #define RAVL_SBFACC_HEADER 1 ///////////////////////////////////////////////////////////////////////// //! file="Ravl/Core/Container/Buffer/SBfAcc.hh" //! lib=RavlCore //! author="Radek Marik" //! docentry="Ravl.Core.Arrays.Buffer" //! date="14/02/97" //! userlevel=Develop //! rcsid="$Id: SBfAcc.hh,v 1.8 2002/04/28 21:55:03 craftit Exp $" #include "Ravl/IndexRange1d.hh" #include "Ravl/BufferAccess.hh" #include "Ravl/Types.hh" namespace RavlN { class BinOStreamC; class BinIStreamC; //: Basic access to buffer with limited size // The class SizeBufferAccessC enables to random indexed access to // a sequentially organised continous part of memory called buffer. // The access functions check if an accessed element is valid only in // debug mode. template class SizeBufferAccessC : public BufferAccessC { public: typedef DataT ElementT; // Constructors, copies, assigment, and destructor // ----------------------------------------------- inline SizeBufferAccessC() : sz(0) {} //: Default constructor. inline SizeBufferAccessC(DataT * bp, SizeT size = 0); // Creates an access to a buffer pointed by the pointer 'bp'. If // 'bp' is 0, the access is not valid. inline SizeBufferAccessC(const BufferAccessC & bp,SizeT s); // Creates an access to a buffer referenced by 'bp' with size 's'. inline SizeBufferAccessC(const SizeBufferAccessC & ba); // Creates a physical copy of the access 'ba'. inline SizeBufferAccessC(const SizeBufferAccessC & ba,SizeT s); // Creates a physical copy of the access 'ba' limited by new size 's'. inline const SizeBufferAccessC & operator=(DataT * bp); // Changes the reference element to the element pointed by 'bp'. // Access to the object // -------------------- inline DataT * DataStart() const { return buff; } // Returns the address of the first element of the buffer. inline SizeT Size() const { return sz; } // Returns the number of elements of the array. inline IndexRangeC Limits() const { return IndexRangeC(0,sz); } // Returns the usable range of indeces expressed by this object. inline IndexRangeC Range() const { return IndexRangeC(0,sz); } // Returns the usable range of indeces expressed by this object. inline IndexC IMin() const { return 0; } // Returns the minimum index of the range of this access. inline IndexC IMax() const { return sz-1; } // Returns the maximum index of the range of this access. inline const DataT & operator[](const IndexC i) const; // Read-only access to the ('i'+1)-th element of the buffer. inline DataT & operator[](const IndexC i); // Read-write access to the ('i'+1)-th element of the buffer. inline const SizeBufferAccessC & SAccess(void) const { return *this; } // Returns this object. // Logical functions // ----------------- inline bool IsEmpty() const { return sz == 0; } // Returns TRUE if the size of the array is zero. inline bool Contains(IndexC i) const { return ((UIntT) i.V()) < sz; } // Returns TRUE if the array contains an item with the index 'i'. // Modifications of the access // --------------------------- inline SizeT ShrinkHigh(SizeT k) { RavlAssert(k <= sz); sz -= k; return sz; } // Changes the number of elements by subtracting the last 'k' elements. inline const SizeBufferAccessC & Swap(SizeBufferAccessC & a); // Exchanges the contents of this buffer with buffer 'a'. inline void Attach(const SizeBufferAccessC & b); // Changes this buffer access to have the same access rights as 'b'. inline void Attach(const BufferAccessC & b, SizeT size); // Changes this buffer access to have the access rights as 'b' limited // for 'size' elements. inline SizeBufferAccessC operator+(SizeT i) const; // Creates the new access object shifted 'i' elements to the right // (towards next elements). The size is descreased to fit the // the original range of this access. // Modifications of the buffer contents // ------------------------------------ void Fill(const DataT & d); // 'd' value is assigned to all elements of the buffer. void CopyFrom(const SizeBufferAccessC &oth); //: Copy contents of another buffer into this one. // NB. Buffers MUST be the same length. void Reverse(); //: Reverse the order of elements in this array in place. SizeBufferAccessC BufferFrom(UIntT first); //: Get an access for this buffer starting from the 'first' element to the end of the buffer. SizeBufferAccessC BufferFrom(UIntT first,UIntT len); //: Get an access for this buffer starting from the 'first' element for 'len' elements. // An error will be generated if the requested buffer isn't contains within this one. bool operator==(const SizeBufferAccessC &ba) const { return (buff == ba.buff) && (sz == ba.sz); } //: Are two accesses the same ? protected: // Copy // ---- SizeBufferAccessC Copy(void) const; // Returns a physical copy of this access pointing to the physical // copy of the accessed buffer in the range accessible by this access. // The new copy is necessary to attach to reference counted buffer // or to delete at the end of the life of this object. private: UIntT sz; // size of the buffer in elements. }; ///////////////////////////////////////////////////////////////////////////// template void SizeBufferAccessC::CopyFrom(const SizeBufferAccessC &oth) { RavlAssert(oth.Size() == Size()); DataT *to = ReferenceElm(); DataT *from = oth.ReferenceElm(); DataT *endOfRow = &to[Size()]; for(;to != endOfRow;to++,from++) *to = *from; } template inline SizeBufferAccessC::SizeBufferAccessC(DataT * bp,SizeT size) : BufferAccessC(bp), sz(size) {} template inline SizeBufferAccessC::SizeBufferAccessC(const BufferAccessC & bp,SizeT s) : BufferAccessC(bp), sz(s) {} template inline SizeBufferAccessC:: SizeBufferAccessC(const SizeBufferAccessC & ba) : BufferAccessC(ba), sz(ba.sz) {} template inline SizeBufferAccessC:: SizeBufferAccessC(const SizeBufferAccessC & ba,SizeT s) : BufferAccessC(ba), sz(s) { #if RAVL_CHECK if (s > ba.Size()) IssueError(__FILE__,__LINE__,"Size %u out of index range 0-%u ",s ,ba.Size()-1); #endif } template inline const SizeBufferAccessC & SizeBufferAccessC::operator=(DataT * bp) { ((BufferAccessC &) *this) = bp; return *this; } template inline const DataT & SizeBufferAccessC::operator[](const IndexC i) const { #if RAVL_CHECK if (!Contains(i)) IssueError(__FILE__,__LINE__,"Index %d out of range 0 - %u ",i.V() ,Size()-1); #endif return BufferAccessC::operator[](i); } template inline DataT & SizeBufferAccessC::operator[](const IndexC i) { #if RAVL_CHECK if (!Contains(i)) IssueError(__FILE__,__LINE__,"Index %d out of range 0 - %u ",i.V() ,Size()-1); #endif return BufferAccessC::operator[](i); } template inline const SizeBufferAccessC & SizeBufferAccessC::Swap(SizeBufferAccessC & a) { BufferAccessC::Swap(a); sz.Swap(a.sz); return *this; } template inline void SizeBufferAccessC::Attach(const SizeBufferAccessC & b) { *this=b; } template inline void SizeBufferAccessC::Attach(const BufferAccessC & b, SizeT size) { ((BufferAccessC &)(*this)) = b; sz=size; } template inline SizeBufferAccessC SizeBufferAccessC::operator+(SizeT i) const { RavlAssert(i <= sz); return SizeBufferAccessC(buff + i, sz - i); } template SizeBufferAccessC SizeBufferAccessC::Copy(void) const { if (IsEmpty()) return SizeBufferAccessC(); DataT * bp = new DataT[Size()]; SizeBufferAccessC b(bp, Size()); DataT *at = DataStart(); DataT *at2 = b.DataStart(); DataT *endOfRow = &at[sz]; for(;at != endOfRow;at++,at2++) *at2 = *at; return b; } template void SizeBufferAccessC::Fill(const DataT & d) { DataT *at = DataStart(); DataT *endOfRow = &at[sz]; for(;at != endOfRow;at++) *at = d; } template void SizeBufferAccessC::Reverse() { DataT *at = &((*this)[IMin()]); DataT *end = &((*this)[IMax()]); DataT tmp; for(;at < end;at++,end--) { tmp = *at; *at = *end; *end = tmp; } } template SizeBufferAccessC SizeBufferAccessC::BufferFrom(UIntT first) { RavlAssert(first < sz); return SizeBufferAccessC(&(ReferenceElm()[first]),sz - first); } template SizeBufferAccessC SizeBufferAccessC::BufferFrom(UIntT first,UIntT len) { RavlAssert((first + len) <= sz); return SizeBufferAccessC(&(ReferenceElm()[first]),len); } template ostream &operator<<(ostream &out,const SizeBufferAccessC &dat) { const DataT *at = dat.DataStart(); const DataT *endOfRow = &at[dat.Size()]; if(dat.Size() == 0) return out; out << *at; at++; for(;at != endOfRow;at++) out << ' ' << *at; return out; } //: Read buffer from stream. // NB. The buffer must be pre-allocated. template istream &operator>>(istream &strm,SizeBufferAccessC &dat) { DataT *at = dat.DataStart(); DataT *endOfRow = &at[dat.Size()]; for(;at != endOfRow;at++) strm >> *at; return strm; } //: Wrtie buffer to stream. // NB. This size of the buffer is NOT written. template BinOStreamC &operator<<(BinOStreamC &out,const SizeBufferAccessC &dat) { const DataT *at = dat.DataStart(); const DataT *endOfRow = &at[dat.Size()]; if(dat.Size() == 0) return out; for(;at != endOfRow;at++) out << *at; return out; } //: Read buffer from stream. // NB. The buffer must be pre-allocated. template BinIStreamC &operator>>(BinIStreamC &strm,SizeBufferAccessC &dat) { DataT *at = dat.DataStart(); DataT *endOfRow = &at[dat.Size()]; for(;at != endOfRow;at++) strm >> *at; return strm; } } #endif