/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef CSV_VVECTOR_HXX #define CSV_VVECTOR_HXX #include // for ptrdiff_t // USED SERVICES #include #include namespace csv { namespace vvector { template struct delete_ptrs { static void Destruct( std::vector< TYPE* > & v) { csv::erase_container_of_heap_ptrs(v); } /// @precond ->it is a valid iterator within v static void Erase( std::vector< TYPE* > & v, typename std::vector< TYPE* >::iterator it2erase ) { delete *it2erase; v.erase(it2erase); } /// @precond ->v.size() > 0 static void PopBack( std::vector< TYPE* > & v ) { delete v.back(); v.pop_back(); } /// @precond ->it is a valid iterator static void ReplacePtr( typename std::vector< TYPE* >::iterator it, DYN TYPE * pass_new ) { delete *it; *it = pass_new; } }; /** One helper class for the ->csv::VirtualVector. Implements a */ template struct keep_ptrs { static void Destruct(std::vector< TYPE* > & v) {} static void Erase( std::vector< TYPE* > & v, typename std::vector< TYPE* >::iterator it2erase ) { v.erase(it2erase); } static void PopBack( std::vector< TYPE* > & v ) { v.pop_back(); } /// @precond ->it is a valid iterator static void ReplacePtr( typename std::vector< TYPE* >::iterator it, TYPE * io_new ) { *it = io_new; } }; } // namespace vvector /** Implements a vector of different implementations of a base class. Implementation has to be by pointers to get the polymorphic behaviour, however access is by references to the base class. @tpl XX The common base class of vector elements. @tpl PTRDEL Has two possible values: vvector::delete_ptrs Elements have to be on the heap and are deleted when removed (default). vvector::keep_ptrs Elements are only referenced and not deleted when removed. */ template > class VirtualVector { public: typedef VirtualVector self; typedef std::vector< DYN XX* > impl_type; typedef typename impl_type::size_type size_type; typedef ptrdiff_t difference_type; class const_iterator; class iterator; // LIFECYCLE VirtualVector(); explicit VirtualVector( int i_size ); ~VirtualVector(); // OPERATORS const XX & operator[]( size_type i_pos ) const; XX & operator[]( size_type i_pos ); // OPERATIONS void push_back( DYN XX & i_drElement ); void pop_back(); iterator insert( iterator i_pos, DYN XX & i_drElement ); void erase( iterator i_pos ); void replace( iterator i_pos, DYN XX & i_drElement ); void reserve( size_type i_size ); // INQUIRY bool empty() const; size_t size() const; const_iterator begin() const; const_iterator end() const; const XX & front() const; const XX & back() const; // ACCESS iterator begin(); iterator end(); XX & front(); XX & back(); private: // Forbidden: VirtualVector(const VirtualVector&); VirtualVector & operator=(const VirtualVector&); // DATA std::vector< DYN XX* > aData; }; /** Should be usable for all STL algorithms. Implements the Random Access Iterator concept. */ template class VirtualVector:: const_iterator // This derivation provides type information for the STL // It introduces the types "value_type" and "difference_type". : public std::iterator { public: typedef VirtualVector my_container; typedef typename my_container::impl_type::const_iterator impl_iterator; // LIFECYCLE const_iterator( impl_iterator i_implIter ) : itImpl(i_implIter) {} /////////// STL ITERATOR CONCEPT IMPLEMENTATION ////////////// // Default Constructible functions: const_iterator() : itImpl() {} // Assignable functions: // Assignment and copy constructor use the compiler generated versions. // Equality Comparable functions: bool operator==( const_iterator i_other ) const { return itImpl == i_other.itImpl; } bool operator!=( const_iterator i_other ) const { return itImpl != i_other.itImpl; } // Trivial Iterator functions: const XX & operator*() const { return *(*itImpl); } // Input Iterator functions: const_iterator & operator++() { ++itImpl; return *this; } const_iterator operator++(int) { return const_iterator(itImpl++); } // Bidirectional Iterator functions: const_iterator & operator--() { --itImpl; return *this; } const_iterator operator--(int) { return const_iterator(itImpl--); } // Less Than Comparable functions: bool operator<( const_iterator i_other ) const { return itImpl < i_other.itImpl; } // Random Access Iterator functions: const_iterator & operator+=( difference_type i_diff ) { itImpl += i_diff; return *this; } const_iterator operator+( difference_type i_diff ) const { const_iterator ret(itImpl); return ret += i_diff; } const_iterator & operator-=( difference_type i_diff ) { itImpl -= i_diff; return *this; } const_iterator operator-( difference_type i_diff ) const { const_iterator ret(itImpl); return ret -= i_diff; } difference_type operator-( const_iterator i_it ) const { return itImpl - i_it.itImpl; } const XX & operator[]( difference_type i_index ) { return *(*itImpl[i_index]); } ////////////////////////////////////////////////////////////////////////// private: friend class VirtualVector; impl_iterator ImplValue() const { return itImpl; } // DATA impl_iterator itImpl; }; /** Should be usable for all STL algorithms. Implements the Random Access Iterator concept. */ template class VirtualVector:: iterator // This derivation provides type information for the STL // It introduces the types "value_type" and "difference_type". : public std::iterator { public: typedef VirtualVector my_container; typedef typename my_container::impl_type::iterator impl_iterator; // LIFECYCLE iterator( impl_iterator i_implIter ) : itImpl(i_implIter) {} /////////// STL ITERATOR CONCEPT IMPLEMENTATION ////////////// // Default Constructible functions: iterator() : itImpl() {} // Assignable functions: // Assignment and copy constructor use the compiler generated versions. // Equality Comparable functions: bool operator==( iterator i_other ) const { return itImpl == i_other.itImpl; } bool operator!=( iterator i_other ) const { return itImpl != i_other.itImpl; } // Trivial Iterator functions: XX & operator*() const { return *(*itImpl); } // Input Iterator functions: iterator & operator++() { ++itImpl; return *this; } iterator operator++(int) { return iterator(itImpl++); } // Bidirectional Iterator functions: iterator & operator--() { --itImpl; return *this; } iterator operator--(int) { return iterator(itImpl--); } // Less Than Comparable functions: bool operator<( iterator i_other ) const { return itImpl < i_other.itImpl; } // Random Access Iterator functions: iterator & operator+=( difference_type i_diff ) { itImpl += i_diff; return *this; } iterator operator+( difference_type i_diff ) const { iterator ret(itImpl); return ret += i_diff; } iterator & operator-=( difference_type i_diff ) { itImpl -= i_diff; return *this; } iterator operator-( difference_type i_diff ) const { iterator ret(itImpl); return ret -= i_diff; } difference_type operator-( iterator i_it ) const { return itImpl - i_it.itImpl; } XX & operator[]( difference_type i_index ) { return *(*itImpl[i_index]); } ////////////////////////////////////////////////////////////////////////// private: friend class VirtualVector; impl_iterator ImplValue() const { return itImpl; } // DATA impl_iterator itImpl; }; // IMPLEMENTATION template inline VirtualVector::VirtualVector() : aData() { } template inline VirtualVector::VirtualVector(int i_size) : aData(i_size, 0) { } template inline VirtualVector::~VirtualVector() { PTRDEL::Destruct(aData); } template inline const XX & VirtualVector::operator[]( size_type i_pos ) const { return *aData[i_pos]; } template inline XX & VirtualVector::operator[]( size_type i_pos ) { return *aData[i_pos]; } template inline void VirtualVector::push_back( DYN XX & i_drElement ) { aData.push_back(&i_drElement); } template inline void VirtualVector::pop_back() { if (NOT aData.empty()) PTRDEL::PopBack(aData); } template inline typename VirtualVector::iterator VirtualVector::insert( iterator i_pos, DYN XX & i_drElement ) { return iterator(aData.insert(i_pos.ImplValue(), &i_drElement)); } template inline void VirtualVector::erase( iterator i_pos ) { PTRDEL::Erase(aData, i_pos.ImplValue()); } template inline void VirtualVector::replace( iterator i_pos, DYN XX & i_drElement ) { PTRDEL::ReplacePtr(*i_pos, &i_drElement); } template inline void VirtualVector::reserve( size_type i_size ) { aData.reserve(i_size); } template inline bool VirtualVector::empty() const { return aData.empty(); } template inline size_t VirtualVector::size() const { return aData.size(); } template inline typename VirtualVector::const_iterator VirtualVector::begin() const { return const_iterator(aData.begin()); } template inline typename VirtualVector::const_iterator VirtualVector::end() const { return const_iterator(aData.end()); } template inline const XX & VirtualVector::front() const { return *aData.front(); } template inline const XX & VirtualVector::back() const { return *aData.back(); } template inline typename VirtualVector::iterator VirtualVector::begin() { return iterator(aData.begin()); } template inline typename VirtualVector::iterator VirtualVector::end() { return iterator(aData.end()); } template inline XX & VirtualVector::front() { return *aData.front(); } template inline XX & VirtualVector::back() { return *aData.back(); } } // namespace csv #endif