OpenWalnut  1.4.0
WMixinVector.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 // PLEASE NOTE THAT THIS IS A COPY FROM THE OSG PROJECT: <osg/MixinVector>
00026 // http://www.openscenegraph.org/projects/osg/attachment/wiki/Legal/LICENSE.txt
00027 
00028 #ifndef WMIXINVECTOR_H
00029 #define WMIXINVECTOR_H
00030 
00031 #include <algorithm>
00032 #include <iostream>
00033 #include <vector>
00034 
00035 #include "WStringUtils.h"
00036 
00037 /**
00038  * This is taken from OpenSceneGraph <osg/MixinVector> but copy and pasted in
00039  * order to reduce dependency to OSG. It follows the orignal documentation:
00040  *
00041  * WMixinVector is a base class that allows inheritance to be used to easily
00042  * emulate derivation from std::vector but without introducing undefined
00043  * behaviour through violation of virtual destructor rules.
00044  *
00045  * @author Neil Groves
00046  **/
00047 template< class ValueT > class WMixinVector
00048 {
00049     /**
00050      * Handy shortcut for the vector type
00051      */
00052     typedef typename std::vector< ValueT > vector_type;
00053 
00054 public:
00055     /**
00056      * Compares to std::vector type
00057      */
00058     typedef typename vector_type::allocator_type allocator_type;
00059 
00060     /**
00061      * Compares to std::vector type
00062      */
00063     typedef typename vector_type::value_type value_type;
00064     /**
00065      * Compares to std::vector type
00066      */
00067     typedef typename vector_type::const_pointer const_pointer;
00068 
00069     /**
00070      * Compares to std::vector type
00071      */
00072     typedef typename vector_type::pointer pointer;
00073 
00074     /**
00075      * Compares to std::vector type
00076      */
00077     typedef typename vector_type::const_reference const_reference;
00078 
00079     /**
00080      * Compares to std::vector type
00081      */
00082     typedef typename vector_type::reference reference;
00083 
00084     /**
00085      * Compares to std::vector type
00086      */
00087     typedef typename vector_type::const_iterator const_iterator;
00088 
00089     /**
00090      * Compares to std::vector type
00091      */
00092     typedef typename vector_type::iterator iterator;
00093 
00094     /**
00095      * Compares to std::vector type
00096      */
00097     typedef typename vector_type::const_reverse_iterator const_reverse_iterator;
00098 
00099     /**
00100      * Compares to std::vector type
00101      */
00102     typedef typename vector_type::reverse_iterator reverse_iterator;
00103 
00104     /**
00105      * Compares to std::vector type
00106      */
00107 
00108     /**
00109      * Compares to std::vector type
00110      */
00111     typedef typename vector_type::size_type size_type;
00112 
00113     /**
00114      * Compares to std::vector type
00115      */
00116     typedef typename vector_type::difference_type difference_type;
00117 
00118     /**
00119      * Empty standard constructor
00120      */
00121     explicit WMixinVector() : _impl()
00122     {
00123     }
00124 
00125     /**
00126      * Constructs a vector of initial_size size where every emlement has its
00127      * default value or the given value.
00128      *
00129      *
00130      * \param initial_size The initial size
00131      * \param fill_value The default value for every element
00132      */
00133     explicit WMixinVector( size_type initial_size, const value_type& fill_value = value_type() )
00134         : _impl( initial_size, fill_value )
00135     {
00136     }
00137 
00138 
00139     /**
00140      * Constructs a new vector out of an iterator of another vector.
00141      *
00142      * \param first Begin of the iterator
00143      * \param last End of the iterator
00144      */
00145     template< class InputIterator > WMixinVector( InputIterator first, InputIterator last )
00146         : _impl( first, last )
00147     {
00148     }
00149 
00150     /**
00151      * Copy constructor for the appropriate vector type
00152      *
00153      * \param other Other std::vector of type vector_type
00154      */
00155     explicit WMixinVector( const vector_type& other )
00156         : _impl( other )
00157     {
00158     }
00159 
00160     /**
00161      * Copy constructor for the WMixinVector itself
00162      *
00163      * \param other Other WMixinVector
00164      */
00165     WMixinVector( const WMixinVector& other )
00166         : _impl( other._impl )
00167     {
00168     }
00169 
00170     /**
00171      * Assignment operator for the appropriate vector type
00172      *
00173      * \param other Other std::vector
00174      *
00175      * \return Reference to the assigned mixin
00176      */
00177     WMixinVector& operator=( const vector_type& other )
00178     {
00179         _impl = other;
00180         return *this;
00181     }
00182 
00183     /**
00184      * Assigment operator for the WMixinVector itself
00185      *
00186      * \param other Other WMixinVector
00187      *
00188      * \return Reference to the assigned mixin
00189      */
00190     WMixinVector& operator=( const WMixinVector& other )
00191     {
00192         _impl = other._impl;
00193         return *this;
00194     }
00195 
00196     /**
00197      * Virtual Destructor
00198      */
00199     virtual ~WMixinVector()
00200     {
00201     }
00202 
00203     /**
00204      * Wrapper around std::vector member function.
00205      */
00206     void clear()
00207     {
00208         _impl.clear();
00209     }
00210 
00211     /**
00212      * Wrapper around std::vector member function.
00213      *
00214      * \param new_size
00215      * \param fill_value
00216      */
00217     void resize( size_type new_size, const value_type& fill_value = value_type() )
00218     {
00219         _impl.resize( new_size, fill_value );
00220     }
00221 
00222     /**
00223      * Wrapper around std::vector member function.
00224      *
00225      * \param new_capacity How many elements will be in this vector
00226      */
00227     void reserve( size_type new_capacity )
00228     {
00229         _impl.reserve( new_capacity );
00230     }
00231 
00232     /**
00233      * Allow also swap with vectors of an appropriate type
00234      *
00235      * \param other To swap with
00236      */
00237     void swap( vector_type& other )
00238     {
00239         _impl.swap( other );
00240     }
00241 
00242     /**
00243      * Wrapper around std::vector member function.
00244      *
00245      * \param other
00246      */
00247     void swap( WMixinVector& other )
00248     {
00249         _impl.swap( other._impl );
00250     }
00251 
00252     /**
00253      * Wrapper around std::vector member function.
00254      *
00255      * \return True if empty otherwise false.
00256      */
00257     bool empty() const
00258     {
00259         return _impl.empty();
00260     }
00261 
00262     /**
00263      * Wrapper around std::vector member function.
00264      *
00265      * \return How many elements this vector has
00266      */
00267     size_type size() const
00268     {
00269         return _impl.size();
00270     }
00271 
00272     /**
00273      * Wrapper around std::vector member function.
00274      *
00275      * \return Its capacity
00276      */
00277     size_type capacity() const
00278     {
00279         return _impl.capacity();
00280     }
00281 
00282     /**
00283      * Wrapper around std::vector member function.
00284      *
00285      * \return Its maximal size
00286      */
00287     size_type max_size() const
00288     {
00289         return _impl.max_size();
00290     }
00291 
00292     /**
00293      * Returns its allocator
00294      *
00295      * \return Its allocator
00296      */
00297     allocator_type get_allocator() const
00298     {
00299         return _impl.get_allocator();
00300     }
00301 
00302     /**
00303      * Wrapper around std::vector member function.
00304      *
00305      * \return Const iterator starting a the first element
00306      */
00307     const_iterator begin() const
00308     {
00309         return _impl.begin();
00310     }
00311 
00312     /**
00313      * Wrapper around std::vector member function.
00314      *
00315      * \return Iterator starting a the first element
00316      */
00317     iterator begin()
00318     {
00319         return _impl.begin();
00320     }
00321 
00322     /**
00323      * Wrapper around std::vector member function.
00324      *
00325      * \return Const iterator starting a the last element
00326      */
00327     const_iterator end() const
00328     {
00329         return _impl.end();
00330     }
00331 
00332     /**
00333      * Wrapper around std::vector member function.
00334      *
00335      * \return Iterator starting a the last element
00336      */
00337     iterator end()
00338     {
00339         return _impl.end();
00340     }
00341 
00342     /**
00343      *  Wrapper around std::vector member function.
00344      *
00345      * \return Const reverse iterator starting a the last element
00346      */
00347     const_reverse_iterator rbegin() const
00348     {
00349         return _impl.rbegin();
00350     }
00351 
00352     /**
00353      *  Wrapper around std::vector member function.
00354      *
00355      * \return Reverse iterator starting a the last element
00356      */
00357     reverse_iterator rbegin()
00358     {
00359         return _impl.rbegin();
00360     }
00361 
00362     /**
00363      *  Wrapper around std::vector member function.
00364      *
00365      * \return Const reverse iterator starting a the first element
00366      */
00367     const_reverse_iterator rend() const
00368     {
00369         return _impl.rend();
00370     }
00371 
00372     /**
00373      *  Wrapper around std::vector member function.
00374      *
00375      * \return Reverse iterator starting a the first element
00376      */
00377     reverse_iterator rend()
00378     {
00379         return _impl.rend();
00380     }
00381 
00382     /**
00383      *  Wrapper around std::vector member function.
00384      *
00385      * \param index Index of the element that is returned
00386      *
00387      * \return Const referenece to the index'th element
00388      */
00389     const_reference operator[]( size_type index ) const
00390     {
00391         return _impl[index];
00392     }
00393 
00394     /**
00395      *  Wrapper around std::vector member function.
00396      *
00397      * \param index Index of the element that is returned
00398      *
00399      * \return Referenece to the index'th element
00400      */
00401     reference operator[]( size_type index )
00402     {
00403         return _impl[index];
00404     }
00405 
00406     /**
00407      *  Wrapper around std::vector member function.
00408      *
00409      * \param index Index of the element that is returned
00410      *
00411      * \return Const referenece to the index'th element
00412      */
00413     const_reference at( size_type index ) const
00414     {
00415         return _impl.at( index );
00416     }
00417 
00418     /**
00419      *  Wrapper around std::vector member function.
00420      *
00421      * \param index Index of the element that is returned
00422      *
00423      * \return Referenece to the index'th element
00424      */
00425     reference at( size_type index )
00426     {
00427         return _impl.at( index );
00428     }
00429 
00430     /**
00431      * Wrapper around std::vector member function.
00432      *
00433      * \param count
00434      * \param value
00435      */
00436     void assign( size_type count, const value_type& value )
00437     {
00438         _impl.assign( count, value );
00439     }
00440 
00441     /**
00442      * Wrapper around std::vector member function.
00443      *
00444      * \param first
00445      * \param last
00446      */
00447     template< class Iter > void assign( Iter first, Iter last )
00448     {
00449         _impl.assign( first, last );
00450     }
00451 
00452     /**
00453      * Wrapper around std::vector member function.
00454      *
00455      * \param value Value to append
00456      */
00457     void push_back( const value_type& value )
00458     {
00459         _impl.push_back( value );
00460     }
00461 
00462     /**
00463      * Wrapper around std::vector member function.
00464      */
00465     void pop_back()
00466     {
00467         _impl.pop_back();
00468     }
00469 
00470     /**
00471      * Wrapper around std::vector member function.
00472      *
00473      * \param where Position where to erase
00474      *
00475      * \return Iterator from the erase
00476      */
00477     iterator erase( iterator where )
00478     {
00479         return _impl.erase( where );
00480     }
00481 
00482     /**
00483      * Wrapper around std::vector member function.
00484      *
00485      * \param first Start from where to erase
00486      * \param last End unti to erase
00487      *
00488      * \return Iterator from erase
00489      */
00490     iterator erase( iterator first, iterator last )
00491     {
00492         return _impl.erase( first, last );
00493     }
00494 
00495     /**
00496      * Wrapper around std::vector member function.
00497      *
00498      * \param where Position where to insert
00499      * \param value Value of the element to insert
00500      *
00501      * \return Iterator from insert
00502      */
00503     iterator insert( iterator where, const value_type& value )
00504     {
00505         return _impl.insert( where, value );
00506     }
00507 
00508     /**
00509      * Wrapper around std::vector member function.
00510      *
00511      * \param where Position where to insert
00512      * \param first Position where to start insert ( First element that should be copied )
00513      * \param last Position where to end insert ( Last element that should be copied )
00514      */
00515     template< class InputIterator > void insert( iterator where, InputIterator first, InputIterator last )
00516     {
00517         _impl.insert( where, first, last );
00518     }
00519 
00520     /**
00521      * Wrapper around std::vector member function.
00522      *
00523      * \param where Position where to insert
00524      * \param count How many elements to insert
00525      * \param value Which value is inserted
00526      */
00527     void insert( iterator where, size_type count, const value_type& value )
00528     {
00529         _impl.insert( where, count, value );
00530     }
00531 
00532     /**
00533      *  Wrapper around std::vector member function.
00534      *
00535      * \return Const reference to last element
00536      */
00537     const_reference back() const
00538     {
00539         return _impl.back();
00540     }
00541 
00542     /**
00543      *  Wrapper around std::vector member function.
00544      *
00545      * \return Reference to last element
00546      */
00547     reference back()
00548     {
00549         return _impl.back();
00550     }
00551 
00552     /**
00553      *  Wrapper around std::vector member function.
00554      *
00555      * \return Const reference to first element
00556      */
00557     const_reference front() const
00558     {
00559         return _impl.front();
00560     }
00561 
00562     /**
00563      *  Wrapper around std::vector member function.
00564      *
00565      * \return Reference to first element
00566      */
00567     reference front()
00568     {
00569         return _impl.front();
00570     }
00571 
00572     /**
00573      * Return this Mixin as its underlying real vector type.
00574      * \warning Use with caution!
00575      *
00576      * \return Reference to its private vector.
00577      */
00578     vector_type& asVector()
00579     {
00580         return _impl;
00581     }
00582 
00583     /**
00584      * Return this Mixin as its underlying real vector type.
00585      *
00586      * \return Const reference to its private vector.
00587      */
00588     const vector_type& asVector() const
00589     {
00590         return _impl;
00591     }
00592 
00593     /**
00594      *  Wrapper around std::vector operator
00595      *
00596      * \param left Left hand side
00597      * \param right Right hand side
00598      *
00599      * \return True if and only if std::vector operator is true
00600      */
00601     friend inline bool operator==( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00602     {
00603         return left._impl == right._impl;
00604     }
00605 
00606     /**
00607      *  Wrapper around std::vector operator
00608      *
00609      * \param left Left hand side
00610      * \param right Right hand side
00611      *
00612      * \return True if and only if std::vector operator is true
00613      */
00614     friend inline bool operator==( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00615     {
00616         return left._impl == right;
00617     }
00618 
00619     /**
00620      *  Wrapper around std::vector operator
00621      *
00622      * \param left Left hand side
00623      * \param right Right hand side
00624      *
00625      * \return True if and only if std::vector operator is true
00626      */
00627     friend inline bool operator==( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00628     {
00629         return left == right._impl;
00630     }
00631 
00632 
00633     /**
00634      *  Wrapper around std::vector operator
00635      *
00636      * \param left Left hand side
00637      * \param right Right hand side
00638      *
00639      * \return True if and only if std::vector operator is true
00640      */
00641     friend inline bool operator!=( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00642     {
00643         return left._impl != right._impl;
00644     }
00645 
00646     /**
00647      *  Wrapper around std::vector operator
00648      *
00649      * \param left Left hand side
00650      * \param right Right hand side
00651      *
00652      * \return True if and only if std::vector operator is true
00653      */
00654     friend inline bool operator!=( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00655     {
00656         return left._impl != right;
00657     }
00658 
00659     /**
00660      *  Wrapper around std::vector operator
00661      *
00662      * \param left Left hand side
00663      * \param right Right hand side
00664      *
00665      * \return True if and only if std::vector operator is true
00666      */
00667     friend inline bool operator!=( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00668     {
00669         return left != right._impl;
00670     }
00671 
00672 
00673     /**
00674      *  Wrapper around std::vector operator
00675      *
00676      * \param left Left hand side
00677      * \param right Right hand side
00678      *
00679      * \return True if and only if std::vector operator is true
00680      */
00681     friend inline bool operator<( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00682     {
00683         return left._impl < right._impl;
00684     }
00685 
00686     /**
00687      *  Wrapper around std::vector operator
00688      *
00689      * \param left Left hand side
00690      * \param right Right hand side
00691      *
00692      * \return True if and only if std::vector operator is true
00693      */
00694     friend inline bool operator<( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00695     {
00696         return left._impl < right;
00697     }
00698 
00699     /**
00700      *  Wrapper around std::vector operator
00701      *
00702      * \param left Left hand side
00703      * \param right Right hand side
00704      *
00705      * \return True if and only if std::vector operator is true
00706      */
00707     friend inline bool operator<( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00708     {
00709         return left < right._impl;
00710     }
00711 
00712 
00713     /**
00714      *  Wrapper around std::vector operator
00715      *
00716      * \param left Left hand side
00717      * \param right Right hand side
00718      *
00719      * \return True if and only if std::vector operator is true
00720      */
00721     friend inline bool operator >( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00722     {
00723         return left._impl > right._impl;
00724     }
00725 
00726     /**
00727      *  Wrapper around std::vector operator
00728      *
00729      * \param left Left hand side
00730      * \param right Right hand side
00731      *
00732      * \return True if and only if std::vector operator is true
00733      */
00734     friend inline bool operator >( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00735     {
00736         return left._impl > right;
00737     }
00738 
00739     /**
00740      *  Wrapper around std::vector operator
00741      *
00742      * \param left Left hand side
00743      * \param right Right hand side
00744      *
00745      * \return True if and only if std::vector operator is true
00746      */
00747     friend inline bool operator >( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00748     {
00749         return left > right._impl;
00750     }
00751 
00752 
00753     /**
00754      *  Wrapper around std::vector operator
00755      *
00756      * \param left Left hand side
00757      * \param right Right hand side
00758      *
00759      * \return True if and only if std::vector operator is true
00760      */
00761     friend inline bool operator<=( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00762     {
00763         return left._impl <= right._impl;
00764     }
00765 
00766     /**
00767      *  Wrapper around std::vector operator
00768      *
00769      * \param left Left hand side
00770      * \param right Right hand side
00771      *
00772      * \return True if and only if std::vector operator is true
00773      */
00774     friend inline bool operator<=( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00775     {
00776         return left._impl <= right;
00777     }
00778 
00779     /**
00780      *  Wrapper around std::vector operator
00781      *
00782      * \param left Left hand side
00783      * \param right Right hand side
00784      *
00785      * \return True if and only if std::vector operator is true
00786      */
00787     friend inline bool operator<=( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00788     {
00789         return left <= right._impl;
00790     }
00791 
00792 
00793     /**
00794      *  Wrapper around std::vector operator
00795      *
00796      * \param left Left hand side
00797      * \param right Right hand side
00798      *
00799      * \return True if and only if std::vector operator is true
00800      */
00801     friend inline bool operator>=( const WMixinVector< ValueT >& left, const WMixinVector< ValueT >& right )
00802     {
00803         return left._impl >= right._impl;
00804     }
00805 
00806     /**
00807      *  Wrapper around std::vector operator
00808      *
00809      * \param left Left hand side
00810      * \param right Right hand side
00811      *
00812      * \return True if and only if std::vector operator is true
00813      */
00814     friend inline bool operator>=( const WMixinVector< ValueT >& left, const std::vector< ValueT >& right )
00815     {
00816         return left._impl >= right;
00817     }
00818 
00819     /**
00820      *  Wrapper around std::vector operator
00821      *
00822      * \param left Left hand side
00823      * \param right Right hand side
00824      *
00825      * \return True if and only if std::vector operator is true
00826      */
00827     friend inline bool operator>=( const std::vector< ValueT >& left, const WMixinVector< ValueT >& right )
00828     {
00829         return left >= right._impl;
00830     }
00831 
00832 private:
00833     /**
00834      * Encapsulated internal vector from which derivation is simulated.
00835      */
00836     vector_type _impl;
00837 };
00838 
00839 /**
00840  * Standard non member wrapper function to swap
00841  *
00842  * \param left Left hand side
00843  * \param right Right hand side
00844  */
00845 template< class ValueT > inline void swap( WMixinVector< ValueT >& left, WMixinVector< ValueT >& right )
00846 {
00847     std::swap( left.asVector(), right.asVector() );
00848 }
00849 
00850 /**
00851  * Standard non member wrapper function to swap
00852  *
00853  * \param left Left hand side
00854  * \param right Right hand side
00855  */
00856 template< class ValueT > inline void swap( WMixinVector< ValueT >& left, std::vector< ValueT >& right )
00857 {
00858     std::swap( left.asVector(), right );
00859 }
00860 
00861 /**
00862  * Standard non member wrapper function to swap
00863  *
00864  * \param left Left hand side
00865  * \param right Right hand side
00866  */
00867 template< class ValueT > inline void swap( std::vector< ValueT >& left, WMixinVector< ValueT >& right )
00868 {
00869     std::swap( left, right.asVector() );
00870 }
00871 
00872 /**
00873  * Writes every mixin vector to an output stream such as cout, if its
00874  * elements have an output operator defined.
00875  *
00876  * \param os The output stream where the elements are written to
00877  * \param v MixinVector containing the elements
00878  * \return The output stream again.
00879  */
00880 template< class ValueT > inline std::ostream& operator<<( std::ostream& os, const WMixinVector< ValueT >& v )
00881 {
00882     using string_utils::operator<<;
00883     os << v.asVector();
00884     return os;
00885 }
00886 
00887 #endif  // WMIXINVECTOR_H