/* Copyright 2015, 2016, Michele Santullo * This file is part of "dindexer". * * "dindexer" is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * "dindexer" is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with "dindexer". If not, see . */ #ifndef id1B822B1775424D879AA6AD1739B5BC91 #define id1B822B1775424D879AA6AD1739B5BC91 #include #include #include #include namespace dinhelp { namespace implem_iop { template class IteratorOnPtr_base : public std::iterator { typedef std::iterator parent_type; public: //Typedefs to be STL-compliant typedef typename parent_type::iterator_category iterator_category; typedef typename parent_type::value_type value_type; typedef typename parent_type::difference_type difference_type; typedef typename parent_type::pointer pointer; typedef typename std::remove_reference::type& reference; IteratorOnPtr_base ( P parPointer, difference_type parSize ); IteratorOnPtr_base ( const IteratorOnPtr_base& parOther ); template explicit IteratorOnPtr_base ( const IteratorOnPtr_base& parOther ); ~IteratorOnPtr_base ( void ); difference_type operator- ( const IteratorOnPtr_base& parOther ) const; bool operator== ( const IteratorOnPtr_base& parOther ) const { return m_pointer == parOther.m_pointer; } bool operator!= ( const IteratorOnPtr_base& parOther ) const { return not operator==(parOther); } bool operator< ( const IteratorOnPtr_base& parOther ) const { return m_pointer < parOther.m_pointer; } bool operator>= ( const IteratorOnPtr_base& parOther ) const { return not operator<(parOther); } bool operator> ( const IteratorOnPtr_base& parOther ) const { return parOther < *this; } bool operator<= ( const IteratorOnPtr_base& parOther ) const { return not operator>(parOther); } P GetPointer ( void ) { return m_pointer; } const P GetPointer ( void ) const { return m_pointer; } #if !defined(NDEBUG) difference_type GetSize ( void ) const { return GetSize(0); } #endif protected: enum { STEP = (I < 0 ? -I : I) }; #if !defined(NDEBUG) difference_type GetSize ( difference_type parAdvance ) const; bool CanAdvance ( difference_type parAdvance ) const; void AlterSize ( difference_type parAdvance ); #endif void MoveIterator ( difference_type parAdvance ); P m_pointer; private: #if !defined(NDEBUG) difference_type m_size; #endif }; } //namespace implem_iop template class IteratorOnPtr : public implem_iop::IteratorOnPtr_base { typedef implem_iop::IteratorOnPtr_base parent_type; enum { STEP = parent_type::STEP }; public: typedef typename parent_type::iterator_category iterator_category; typedef typename parent_type::value_type value_type; typedef typename parent_type::difference_type difference_type; typedef typename parent_type::pointer pointer; typedef typename parent_type::reference reference; IteratorOnPtr ( void ); IteratorOnPtr ( P parPointer, difference_type parSize ); IteratorOnPtr ( const IteratorOnPtr& parOther ) : parent_type(parOther) { return; } template IteratorOnPtr ( const IteratorOnPtr& parOther ) : parent_type(parOther) {} ~IteratorOnPtr ( void ); IteratorOnPtr& operator++ ( void ); //pre IteratorOnPtr operator++ ( int ); //post IteratorOnPtr& operator-- ( void ); IteratorOnPtr operator-- ( int ); reference operator* ( void ); pointer operator-> ( void ); using parent_type::operator-; IteratorOnPtr operator+ ( difference_type parOther ) const; IteratorOnPtr operator- ( difference_type parOther ) const; IteratorOnPtr& operator+= ( difference_type parOther ); IteratorOnPtr& operator-= ( difference_type parOther ); protected: private: }; namespace implem_iop { ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template #if !defined(NDEBUG) IteratorOnPtr_base::IteratorOnPtr_base (P parPointer, difference_type parSize) : m_pointer(parPointer), m_size(parSize) #else IteratorOnPtr_base::IteratorOnPtr_base (P parPointer, difference_type) : m_pointer(parPointer) #endif { static_assert(I != 0, "Step must be non-zero"); } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template template IteratorOnPtr_base::IteratorOnPtr_base (const IteratorOnPtr_base& parOther) { m_pointer = parOther.GetPointer(); #if !defined(NDEBUG) m_size = parOther.GetSize(); #endif } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template IteratorOnPtr_base::IteratorOnPtr_base (const IteratorOnPtr_base& parOther) { m_pointer = parOther.m_pointer; #if !defined(NDEBUG) m_size = parOther.m_size; #endif } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template IteratorOnPtr_base::~IteratorOnPtr_base() { } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template typename IteratorOnPtr_base::difference_type IteratorOnPtr_base::operator- (const IteratorOnPtr_base& parOther) const { if (I > 0) return m_pointer - parOther.m_pointer; else return parOther.m_pointer - m_pointer; } #if !defined(NDEBUG) ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template typename IteratorOnPtr_base::difference_type IteratorOnPtr_base::GetSize (difference_type parAdvance) const { return m_size - STEP * parAdvance; } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template bool IteratorOnPtr_base::CanAdvance (difference_type parAdvance) const { return (m_size >= STEP * parAdvance); } ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template void IteratorOnPtr_base::AlterSize (difference_type parAdvance) { m_size = GetSize(parAdvance); } #endif ///--------------------------------------------------------------------- ///--------------------------------------------------------------------- template void IteratorOnPtr_base::MoveIterator (difference_type parAdvance) { #if !defined(NDEBUG) assert(CanAdvance(parAdvance)); AlterSize(parAdvance); #endif m_pointer += I * parAdvance; } } //namespace implem_iop ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr::IteratorOnPtr() : parent_type(NULL, 0) { } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr::IteratorOnPtr (P parPointer, difference_type parSize) : parent_type(parPointer, parSize) { } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr::~IteratorOnPtr() { } ///------------------------------------------------------------------------- ///Pre-increment. ///------------------------------------------------------------------------- template IteratorOnPtr& IteratorOnPtr::operator++() { this->MoveIterator(1); return *this; } ///------------------------------------------------------------------------- ///Post-increment. ///------------------------------------------------------------------------- template IteratorOnPtr IteratorOnPtr::operator++ (int) { IteratorOnPtr retVal(*this); this->MoveIterator(1); return retVal; } ///------------------------------------------------------------------------- ///Pre-decrement. ///------------------------------------------------------------------------- template IteratorOnPtr& IteratorOnPtr::operator--() { this->MoveIterator(-1); return *this; } ///------------------------------------------------------------------------- ///Post-decrement. ///------------------------------------------------------------------------- template IteratorOnPtr IteratorOnPtr::operator-- (int) { IteratorOnPtr retVal(*this); this->MoveIterator(-1); return retVal; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename IteratorOnPtr::reference IteratorOnPtr::operator*() { return *(this->m_pointer); } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template typename IteratorOnPtr::pointer IteratorOnPtr::operator->() { return this->m_pointer; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr IteratorOnPtr::operator+ (difference_type parOther) const { IteratorOnPtr retVal(*this); retVal += parOther; return retVal; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr IteratorOnPtr::operator- (difference_type parOther) const { IteratorOnPtr retVal(*this); retVal -= parOther; return retVal; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr& IteratorOnPtr::operator+= (difference_type parOther) { this->MoveIterator(parOther); return *this; } ///------------------------------------------------------------------------- ///------------------------------------------------------------------------- template IteratorOnPtr& IteratorOnPtr::operator-= (difference_type parOther) { this->MoveIterator(-parOther); return *this; } } //namespace dinhelp #endif