Range.h
Go to the documentation of this file.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
00075 template <class CONTAINER>
00076 class Range_ : public RangeBase_
00077 {
00078 public:
00079
00080 typedef std::pair<typename CONTAINER::const_iterator,
00081 typename CONTAINER::const_iterator> Base ;
00082
00083 public:
00084
00086 typedef CONTAINER Container ;
00087 typedef typename Container::value_type value_type ;
00088 typedef typename Container::const_iterator iterator ;
00089 typedef typename Container::const_iterator const_iterator ;
00090 typedef typename Container::const_reverse_iterator reverse_iterator ;
00091 typedef typename Container::const_reverse_iterator const_reverse_iterator ;
00092 typedef typename Container::const_reference reference ;
00093 typedef typename Container::const_reference const_reference ;
00095 typedef std::pair<iterator,iterator> _Base ;
00096 typedef Range_<Container> _Self ;
00097
00098 public:
00099
00101 Range_() : m_base( iterator() , iterator() ) {};
00106 Range_( iterator ibegin , iterator iend ) : m_base ( ibegin , iend ) {} ;
00110 Range_( const Base& base ) : m_base( base ) {};
00114 Range_( const Container& cont ) : m_base( cont.begin() , cont.end() ) {} ;
00115
00116
00117
00118 Range_( iterator ibegin ) : m_base( ibegin , ibegin ) {};
00120 ~Range_(){};
00121
00123 inline bool empty () const { return m_base.second == m_base.first ; }
00125 inline size_t size () const
00126 { return std::distance ( m_base.first , m_base.second ) ; }
00128 inline iterator begin () const { return m_base.first ; }
00130 inline iterator end () const { return m_base.second ; }
00132 inline reverse_iterator rbegin () const { return reverse_iterator ( end () ) ; }
00134 inline reverse_iterator rend () const { return reverse_iterator ( begin () ) ; }
00136 inline const_reference front () const { return *( begin () ) ; }
00138 inline const_reference back () const
00139 {
00140 const_iterator i = end() ;
00141 std::advance ( i , -1 ) ;
00142 return *i ;
00143 }
00144
00146 inline Range_ slice( long index1 , long index2 ) const
00147 {
00148
00149 if ( empty() || index1 == index2 ) { return Range_() ; }
00150
00151 if ( index1 < 0 ) { index1 += size () ; }
00152 if ( index2 < 0 ) { index2 += size () ; }
00153
00154 if ( index1 < 0 ) { return Range_ () ; }
00155 if ( index2 < index1 ) { return Range_ () ; }
00156
00157 if ( index1 > (long) size () ) { return Range_() ; }
00158 if ( index2 > (long) size () ) { index2 = size() ; }
00159
00160 const_iterator i1 = begin() ;
00161 std::advance ( i1 , index1 ) ;
00162 const_iterator i2 = begin() ;
00163 std::advance ( i2 , index2 ) ;
00164
00165 return Range_( i1 , i2 ) ;
00166 }
00167
00172 inline const_reference operator () ( const size_t index ) const
00173 {
00174 const_iterator i = begin() ;
00175 std::advance ( i , index ) ;
00176 return *i ;
00177 }
00182 inline const_reference operator [] ( const long index ) const
00183 { return (*this)( index ) ; }
00189 inline const_reference at ( const long index ) const
00190 {
00191 if ( index < 0 || index >= (long) size () )
00192 { Gaudi::details::rangeException( index , size() ) ; }
00193 return (*this) ( index );
00194 }
00195
00196 public:
00197
00199 bool operator< ( const Range_& right ) const
00200 {
00201 return std::lexicographical_compare
00202 ( begin () , end () , right.begin () , right.end () ) ;
00203 }
00205 bool operator< ( const Container& right ) const
00206 {
00207 return std::lexicographical_compare
00208 ( begin () , end () , right.begin () , right.end () ) ;
00209 }
00210
00211 public:
00212
00214 bool operator==( const Range_& right ) const
00215 {
00216 if ( &right == this ) { return true ; }
00217 if ( right.size () != size () ) { return false ; }
00218 return std::equal ( begin () , end () , right.begin() ) ;
00219 }
00221 bool operator==( const Container& right ) const
00222 {
00223 if ( right.size () != size () ) { return false ; }
00224 return std::equal ( begin () , end () , right.begin() ) ;
00225 }
00226
00227 public:
00228
00230 bool operator! () const { return empty () ; }
00231
00232 public:
00233
00235 operator const Base& () const { return base () ; }
00237 inline const Base& base () const { return m_base ; }
00238
00239 private:
00240
00241
00242 Base m_base ;
00243
00244 };
00245
00273 template <class CONTAINER>
00274 inline
00275 Range_<CONTAINER>
00276 range ( const CONTAINER& cnt )
00277 { return Range_<CONTAINER>( cnt.begin() , cnt.end() ) ; }
00278
00279 }
00280
00281
00282
00283 #endif // GAUDI_RANGE_H
00284