00001 #ifndef PhysicsTools_Utilities_Selection_h 00002 #define PhysicsTools_Utilities_Selection_h 00003 #include <vector> 00004 00005 template<typename C, 00006 typename Selector, 00007 typename StoreContainer = std::vector<const typename C::value_type *> > 00008 class Selection { 00009 public: 00010 typedef typename C::value_type value_type; 00011 typedef typename C::size_type size_type; 00012 typedef value_type & reference; 00013 typedef const value_type & const_reference; 00014 Selection( const C & c, const Selector & sel ) : 00015 select_( sel ) { 00016 for( typename C::const_iterator i = c.begin(); i != c.end(); ++i ) { 00017 if ( select_( *i ) ) selected_.push_back( & * i ); 00018 } 00019 } 00020 class const_iterator { 00021 public: 00022 typedef typename Selection<C,Selector,StoreContainer>::value_type value_type; 00023 typedef value_type * pointer; 00024 typedef value_type & reference; 00025 typedef ptrdiff_t difference_type; 00026 typedef typename StoreContainer::const_iterator::iterator_category iterator_category; 00027 const_iterator(const typename StoreContainer::const_iterator & it) : i(it) { } 00028 const_iterator(const const_iterator & it) : i(it.i) { } 00029 const_iterator() {} 00030 const_iterator & operator=(const const_iterator & it) { i = it.i; return *this; } 00031 const_iterator& operator++() { ++i; return *this; } 00032 const_iterator operator++(int) { const_iterator ci = *this; ++i; return ci; } 00033 const_iterator& operator--() { --i; return *this; } 00034 const_iterator operator--(int) { const_iterator ci = *this; --i; return ci; } 00035 difference_type operator-(const const_iterator & o) const { return i - o.i; } 00036 const_iterator operator+(difference_type n) const { return const_iterator(i + n); } 00037 const_iterator operator-(difference_type n) const { return const_iterator(i - n); } 00038 bool operator<(const const_iterator & o) const { return i < o.i; } 00039 bool operator==(const const_iterator& ci) const { return i == ci.i; } 00040 bool operator!=(const const_iterator& ci) const { return i != ci.i; } 00041 const value_type & operator *() const { return **i; } 00042 const value_type * operator->() const { return & (operator*()); } 00043 const_iterator & operator +=(difference_type d) { i += d; return *this; } 00044 const_iterator & operator -=(difference_type d) { i -= d; return *this; } 00045 private: 00046 typename StoreContainer::const_iterator i; 00047 }; 00048 const_iterator begin() const { return const_iterator( selected_.begin() ); } 00049 const_iterator end() const { return const_iterator( selected_.end() ); } 00050 size_type size() const { return selected_.size(); } 00051 bool empty() const { return selected_.empty(); } 00052 const_reference operator[]( size_type i ) { return * selected_[i]; } 00053 private: 00054 Selector select_; 00055 StoreContainer selected_; 00056 }; 00057 00058 #endif