AutoRefVector.h

Go to the documentation of this file.
00001 
00002 //    Copyright 2004, SenseGraphics AB
00003 //
00004 //    This file is part of H3D API.
00005 //
00006 //    H3D API is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    H3D API is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with H3D API; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 //
00020 //    A commercial license is also available. Please contact us at 
00021 //    www.sensegraphics.com for more information.
00022 //
00023 //
00027 //
00029 #ifndef __AUTOREFVECTOR_H__
00030 #define __AUTOREFVECTOR_H__
00031 
00032 #include "H3DApi.h"
00033 #include <vector>
00034 #include <algorithm>
00035 
00036 using namespace std;
00037 
00038 namespace H3D {
00043   template< class NodeClass >
00044   class AutoRefVector : private vector<NodeClass*> {
00045   public:
00047     typedef typename vector<NodeClass*>::value_type value_type;
00049     typedef typename vector<NodeClass*>::pointer pointer;
00051     typedef typename vector<NodeClass*>::const_reference const_reference;
00053     typedef typename vector<NodeClass*>::size_type size_type;
00055     typedef typename vector<NodeClass*>::difference_type difference_type; 
00057     typedef typename vector<NodeClass*>::const_iterator const_iterator;
00059     typedef typename vector<NodeClass*>::const_reverse_iterator 
00060     const_reverse_iterator;
00061 
00063     inline AutoRefVector() {}
00064 
00066     inline AutoRefVector( const vector<NodeClass *> &v ) : 
00067       vector<NodeClass*>( v ) {
00068       refAll();
00069     }
00070 
00072     inline AutoRefVector( const AutoRefVector<NodeClass> &v ) : 
00073       vector<NodeClass*>( v ) {
00074       refAll();
00075     }
00076 
00078     inline AutoRefVector( size_type n ):
00079       vector< NodeClass * >( n ) {}
00080 
00082     inline virtual ~AutoRefVector() {
00083       clear();
00084     }
00085 
00087     inline AutoRefVector<NodeClass> 
00088     &operator=( const AutoRefVector<NodeClass> &v ) {
00089       if( this != &v ) {
00090         unrefAll();      
00091         vector<NodeClass*>::operator=( v );
00092         refAll();
00093       }
00094       return *this;
00095     }
00096 
00098     inline AutoRefVector<NodeClass> &operator=( 
00099                                                const vector<NodeClass *> &v ) {
00100       // temporarily add an extra reference to the nodes in v so
00101       // they are not accidentally removed in unrefAll()
00102       for( typename vector< NodeClass * >::const_iterator i = v.begin();
00103            i != v.end();
00104            i++ ) 
00105         (*i)->ref();
00106       unrefAll();
00107       vector<NodeClass*>::operator=( v );
00108       refAll();
00109 
00110       // remove the temporary references.
00111       for( typename vector< NodeClass * >::const_iterator i = v.begin();
00112            i != v.end();
00113            i++ ) 
00114         (*i)->unref();
00115       return *this;
00116     }
00117 
00119     inline const_iterator begin() const { 
00120       return vector<NodeClass*>::begin();
00121     }
00122       
00124     inline const_iterator end() const { return vector<NodeClass*>::end(); }
00125 
00126         
00129     inline const_reverse_iterator rbegin() const { 
00130       return vector<NodeClass*>::rbegin();
00131     }
00132       
00135     inline const_reverse_iterator rend() const { 
00136       return vector<NodeClass*>::rend(); 
00137     }
00138 
00140     inline size_type size() const { 
00141       return vector<NodeClass*>::size(); 
00142     }
00143 
00145     inline size_type max_size() const {
00146       return vector<NodeClass*>::max_size();
00147     }
00148         
00151     inline size_type capacity() const { 
00152       return vector<NodeClass*>::capacity(); 
00153     }
00154         
00156     inline void swap( AutoRefVector<NodeClass> &x ) {
00157       vector<NodeClass*>::swap( x );
00158     }
00159 
00161     inline void swap( vector<NodeClass*> &x ) {
00162       unrefAll();
00163       vector<NodeClass*>::swap( x );
00164       refAll();
00165     }
00166         
00174     inline void reserve( size_t s ) { vector<NodeClass*>::reserve( s ); }
00175 
00177     inline virtual void resize( size_t n, NodeClass * t = NULL ) {
00178       if( size() > n ) {
00179         for( unsigned int i = size() - 1; i >= n; i-- )
00180           unref( vector<NodeClass*>::operator[]( i ) );
00181       }
00182       vector<NodeClass*>::resize( n, t );
00183     }
00184 
00186     inline bool empty() const { return vector<NodeClass*>::empty(); }
00191     inline const_reference operator[](size_type n) const {
00192       return vector<NodeClass*>::operator[]( n );
00193     }
00195     inline void set( size_type i, const value_type &v ) {
00196       vector<NodeClass*>::operator[]( i ) = v;
00197     }
00199     inline const_reference front() const { return vector<NodeClass*>::front(); }
00200 
00202     inline const_reference back() const { return vector<NodeClass*>::back(); }
00203 
00205     inline void push_back( const value_type &x ) {
00206       ref( x );
00207       vector< NodeClass * >::push_back( x );
00208     }
00209 
00211     void pop_back() {
00212       unref( back() );
00213       vector< NodeClass * >::pop_back();
00214     }
00215         
00217     inline void clear() {
00218       unrefAll();
00219       vector<NodeClass*>::clear();
00220     }
00221 
00223     inline virtual void erase( NodeClass *a ) {
00224       typename vector<NodeClass * >::iterator i = 
00225         std::find( vector<NodeClass*>::begin(), 
00226                    vector<NodeClass*>::end(), 
00227                    a );
00228       if( i != end() ) {
00229         unref( *i );
00230         vector<NodeClass*>::erase( i );
00231       } 
00232     }
00233 
00234   protected:
00237     inline virtual void ref( NodeClass *n ) const {
00238       if( n ) {
00239         n->ref();
00240       }
00241     }
00242 
00245     inline virtual void unref( NodeClass *n ) const {
00246       if( n ) {
00247         n->unref();
00248       }
00249     }
00250 
00252     inline void refAll() const {
00253       for( const_iterator i = vector<NodeClass*>::begin(); 
00254            i != vector<NodeClass*>::end(); ++i ) 
00255         ref( *i );
00256     }
00257 
00259     inline void unrefAll() const {
00260       for( const_iterator i = vector<NodeClass*>::begin(); 
00261            i != vector<NodeClass*>::end(); ++i ) 
00262         unref( *i );
00263     }
00264   };
00265 }
00266     
00267 #endif

Generated on Thu Aug 24 12:38:32 2006 for H3D API by  doxygen 1.4.5