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 #include "GaudiKernel/Kernel.h"
00014
00030
00031 namespace Gaudi
00032 {
00033 namespace details
00034 {
00035
00041 GAUDI_API void rangeException
00042 ( const long index ,
00043 const size_t size ) ;
00044
00045 }
00046
00052 struct RangeBase_ {} ;
00053
00076 template <class CONTAINER>
00077 class Range_ : public RangeBase_
00078 {
00079 public:
00080
00081 typedef std::pair<typename CONTAINER::const_iterator,
00082 typename CONTAINER::const_iterator> Base ;
00083
00084 public:
00085
00087 typedef CONTAINER Container ;
00088 typedef typename Container::value_type value_type ;
00089 typedef typename Container::const_iterator iterator ;
00090 typedef typename Container::const_iterator const_iterator ;
00091 typedef typename Container::const_reverse_iterator reverse_iterator ;
00092 typedef typename Container::const_reverse_iterator const_reverse_iterator ;
00093 typedef typename Container::const_reference reference ;
00094 typedef typename Container::const_reference const_reference ;
00096 typedef std::pair<iterator,iterator> _Base ;
00097 typedef Range_<Container> _Self ;
00098
00099 public:
00100
00102 Range_() : m_base( iterator() , iterator() ) {}
00107 Range_( iterator ibegin , iterator iend ) : m_base ( ibegin , iend ) {}
00111 Range_( const Base& base ) : m_base( base ) {}
00115 Range_( const Container& cont ) : m_base( cont.begin() , cont.end() ) {}
00116
00117
00118
00119 Range_( iterator ibegin ) : m_base( ibegin , ibegin ) {}
00121 ~Range_(){}
00122
00124 inline bool empty () const { return m_base.second == m_base.first ; }
00126 inline size_t size () const
00127 { return std::distance ( m_base.first , m_base.second ) ; }
00129 inline iterator begin () const { return m_base.first ; }
00131 inline iterator end () const { return m_base.second ; }
00133 inline reverse_iterator rbegin () const { return reverse_iterator ( end () ) ; }
00135 inline reverse_iterator rend () const { return reverse_iterator ( begin () ) ; }
00137 inline const_reference front () const { return *( begin () ) ; }
00139 inline const_reference back () const
00140 {
00141 const_iterator i = end() ;
00142 std::advance ( i , -1 ) ;
00143 return *i ;
00144 }
00145
00147 inline Range_ slice( long index1 , long index2 ) const
00148 {
00149
00150 if ( empty() || index1 == index2 ) { return Range_() ; }
00151
00152 if ( index1 < 0 ) { index1 += size () ; }
00153 if ( index2 < 0 ) { index2 += size () ; }
00154
00155 if ( index1 < 0 ) { return Range_ () ; }
00156 if ( index2 < index1 ) { return Range_ () ; }
00157
00158 if ( index1 > (long) size () ) { return Range_() ; }
00159 if ( index2 > (long) size () ) { index2 = size() ; }
00160
00161 const_iterator i1 = begin() ;
00162 std::advance ( i1 , index1 ) ;
00163 const_iterator i2 = begin() ;
00164 std::advance ( i2 , index2 ) ;
00165
00166 return Range_( i1 , i2 ) ;
00167 }
00168
00173 inline const_reference operator () ( const size_t index ) const
00174 {
00175 const_iterator i = begin() ;
00176 std::advance ( i , index ) ;
00177 return *i ;
00178 }
00183 inline const_reference operator [] ( const long index ) const
00184 { return (*this)( index ) ; }
00190 inline const_reference at ( const long index ) const
00191 {
00192 if ( index < 0 || index >= (long) size () )
00193 { Gaudi::details::rangeException( index , size() ) ; }
00194 return (*this) ( index );
00195 }
00196
00197 public:
00198
00200 bool operator< ( const Range_& right ) const
00201 {
00202 return std::lexicographical_compare
00203 ( begin () , end () , right.begin () , right.end () ) ;
00204 }
00206 bool operator< ( const Container& right ) const
00207 {
00208 return std::lexicographical_compare
00209 ( begin () , end () , right.begin () , right.end () ) ;
00210 }
00211
00212 public:
00213
00215 bool operator==( const Range_& right ) const
00216 {
00217 if ( &right == this ) { return true ; }
00218 if ( right.size () != size () ) { return false ; }
00219 return std::equal ( begin () , end () , right.begin() ) ;
00220 }
00222 bool operator==( const Container& right ) const
00223 {
00224 if ( right.size () != size () ) { return false ; }
00225 return std::equal ( begin () , end () , right.begin() ) ;
00226 }
00227
00228 public:
00229
00231 bool operator! () const { return empty () ; }
00232
00233 public:
00234
00236 operator const Base& () const { return base () ; }
00238 inline const Base& base () const { return m_base ; }
00239
00240 private:
00241
00242
00243 Base m_base ;
00244
00245 };
00246
00274 template <class CONTAINER>
00275 inline
00276 Range_<CONTAINER>
00277 range ( const CONTAINER& cnt )
00278 { return Range_<CONTAINER>( cnt.begin() , cnt.end() ) ; }
00279
00280 }
00281
00282
00283
00284 #endif // GAUDI_RANGE_H
00285