00001
00002
00003 #ifndef GAUDI_RANGE_H
00004 #define GAUDI_RANGE_H 1
00005
00006
00007
00008
00009
00010 #include <utility>
00011 #include <vector>
00012 #include <algorithm>
00013
00029
00030 namespace Gaudi
00031 {
00032 namespace details
00033 {
00034
00040 void rangeException
00041 ( const long index ,
00042 const size_t size ) ;
00043
00044 }
00045
00051 struct RangeBase_
00052 {
00053 #ifdef _WIN32
00054 virtual ~RangeBase_() {}
00055 #else
00056 protected :
00057 ~RangeBase_ (){}
00058 #endif
00059 } ;
00060
00083 template <class CONTAINER>
00084 class Range_ : public RangeBase_
00085 {
00086 public:
00087
00088 typedef std::pair<typename CONTAINER::const_iterator,
00089 typename CONTAINER::const_iterator> Base ;
00090
00091 public:
00092
00094 typedef CONTAINER Container ;
00095 typedef typename Container::value_type value_type ;
00096 typedef typename Container::const_iterator iterator ;
00097 typedef typename Container::const_iterator const_iterator ;
00098 typedef typename Container::const_reverse_iterator reverse_iterator ;
00099 typedef typename Container::const_reverse_iterator const_reverse_iterator ;
00100 typedef typename Container::const_reference reference ;
00101 typedef typename Container::const_reference const_reference ;
00103 typedef std::pair<iterator,iterator> _Base ;
00104 typedef Range_<Container> _Self ;
00105
00106 public:
00107
00109 Range_() : m_base( iterator() , iterator() ) {};
00114 Range_( iterator ibegin , iterator iend ) : m_base ( ibegin , iend ) {} ;
00118 Range_( const Base& base ) : m_base( base ) {};
00122 Range_( const Container& cont ) : m_base( cont.begin() , cont.end() ) {} ;
00123
00124
00125
00126 Range_( iterator ibegin ) : m_base( ibegin , ibegin ) {};
00128 ~Range_(){};
00129
00131 inline bool empty () const { return m_base.second == m_base.first ; }
00133 inline size_t size () const
00134 { return std::distance ( m_base.first , m_base.second ) ; }
00136 inline iterator begin () const { return m_base.first ; }
00138 inline iterator end () const { return m_base.second ; }
00140 inline reverse_iterator rbegin () const { return reverse_iterator ( end () ) ; }
00142 inline reverse_iterator rend () const { return reverse_iterator ( begin () ) ; }
00144 inline const_reference front () const { return *( begin () ) ; }
00146 inline const_reference back () const
00147 {
00148 const_iterator i = end() ;
00149 std::advance ( i , -1 ) ;
00150 return *i ;
00151 }
00152
00154 inline Range_ slice( long index1 , long index2 ) const
00155 {
00156
00157 if ( empty() || index1 == index2 ) { return Range_() ; }
00158
00159 if ( index1 < 0 ) { index1 += size () ; }
00160 if ( index2 < 0 ) { index2 += size () ; }
00161
00162 if ( index1 < 0 ) { return Range_ () ; }
00163 if ( index2 < index1 ) { return Range_ () ; }
00164
00165 if ( index1 > (long) size () ) { return Range_() ; }
00166 if ( index2 > (long) size () ) { index2 = size() ; }
00167
00168 const_iterator i1 = begin() ;
00169 std::advance ( i1 , index1 ) ;
00170 const_iterator i2 = begin() ;
00171 std::advance ( i2 , index2 ) ;
00172
00173 return Range_( i1 , i2 ) ;
00174 }
00175
00180 inline const_reference operator () ( const size_t index ) const
00181 {
00182 const_iterator i = begin() ;
00183 std::advance ( i , index ) ;
00184 return *i ;
00185 }
00190 inline const_reference operator [] ( const long index ) const
00191 { return (*this)( index ) ; }
00197 inline const_reference at ( const long index ) const
00198 {
00199 if ( index < 0 || index >= (long) size () )
00200 { Gaudi::details::rangeException( index , size() ) ; }
00201 return (*this) ( index );
00202 }
00203
00204 public:
00205
00207 bool operator< ( const Range_& right ) const
00208 {
00209 return std::lexicographical_compare
00210 ( begin () , end () , right.begin () , right.end () ) ;
00211 }
00213 bool operator< ( const Container& right ) const
00214 {
00215 return std::lexicographical_compare
00216 ( begin () , end () , right.begin () , right.end () ) ;
00217 }
00218
00219 public:
00220
00222 bool operator==( const Range_& right ) const
00223 {
00224 if ( &right == this ) { return true ; }
00225 if ( right.size () != size () ) { return false ; }
00226 return std::equal ( begin () , end () , right.begin() ) ;
00227 }
00229 bool operator==( const Container& right ) const
00230 {
00231 if ( right.size () != size () ) { return false ; }
00232 return std::equal ( begin () , end () , right.begin() ) ;
00233 }
00234
00235 public:
00236
00238 bool operator! () const { return empty () ; }
00239
00240 public:
00241
00243 operator const Base& () const { return base () ; }
00245 inline const Base& base () const { return m_base ; }
00246
00247 private:
00248
00249
00250 Base m_base ;
00251
00252 };
00253
00281 template <class CONTAINER>
00282 inline
00283 Range_<CONTAINER>
00284 range ( const CONTAINER& cnt )
00285 { return Range_<CONTAINER>( cnt.begin() , cnt.end() ) ; }
00286
00287 }
00288
00289
00290
00291 #endif // GAUDI_RANGE_H
00292