![]() |
|
|
Generated: 8 Jan 2009 |
00001 // $Id: Range.h,v 1.2 2008/11/03 11:24:47 marcocle Exp $ 00002 // ============================================================================ 00003 #ifndef GAUDI_RANGE_H 00004 #define GAUDI_RANGE_H 1 00005 // ============================================================================ 00006 // Include files 00007 // ============================================================================ 00008 // STD & STL 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 /* constructor of empty range/sequence 00124 * @param ibegin iterator to begin of empty sequence 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 // trivial cases 00157 if ( empty() || index1 == index2 ) { return Range_() ; } // RETURN 00158 // adjust indices 00159 if ( index1 < 0 ) { index1 += size () ; } 00160 if ( index2 < 0 ) { index2 += size () ; } 00161 // check 00162 if ( index1 < 0 ) { return Range_ () ; } // RETURN 00163 if ( index2 < index1 ) { return Range_ () ; } // RETURN 00164 00165 if ( index1 > (long) size () ) { return Range_() ; } // RETURN 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 // construct the slice 00173 return Range_( i1 , i2 ) ; // RETURN 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 ; } // RETURN 00225 if ( right.size () != size () ) { return false ; } // RETURN 00226 return std::equal ( begin () , end () , right.begin() ) ; 00227 } 00229 bool operator==( const Container& right ) const 00230 { 00231 if ( right.size () != size () ) { return false ; } // RETURN 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 // the base itself 00250 Base m_base ; 00251 // ======================================================================== 00252 }; // end of class Range_ 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 } // end of namespace Gaudi 00288 // ============================================================================ 00289 // The END 00290 // ============================================================================ 00291 #endif // GAUDI_RANGE_H 00292 // ============================================================================