00001 #ifndef DataFormats_Common_RefGetter_h
00002 #define DataFormats_Common_RefGetter_h
00003
00004 #include <algorithm>
00005 #include <vector>
00006 #include <iostream>
00007 #include <utility>
00008 #include "boost/concept_check.hpp"
00009 #include "boost/iterator/indirect_iterator.hpp"
00010 #include "DataFormats/Common/interface/traits.h"
00011 #include "DataFormats/Common/interface/Ref.h"
00012 #include "DataFormats/Common/interface/Handle.h"
00013 #include "DataFormats/Common/interface/LazyGetter.h"
00014 #include "FWCore/Utilities/interface/EDMException.h"
00015
00016 namespace edm {
00017
00018
00019
00020 template <class T> class RefGetter {
00021 BOOST_CLASS_REQUIRE(T, boost, LessThanComparableConcept);
00022
00023 public:
00024
00025 typedef Ref< LazyGetter<T>, RegionIndex<T>, FindRegion<T> > region_ref;
00026 typedef std::vector<region_ref> collection_type;
00027 typedef boost::indirect_iterator<typename collection_type::const_iterator> const_iterator;
00028 typedef std::vector<T> record_type;
00029 typedef std::pair<typename record_type::const_iterator, typename record_type::const_iterator> record_pair;
00030
00032 RefGetter(uint32_t=50000);
00033
00035 RefGetter(const edm::Handle< LazyGetter<T> >&, const std::vector<uint32_t>&);
00036
00038 void reserve(uint32_t);
00039
00041 void swap(RefGetter& other);
00042
00044 void push_back(const edm::Handle<LazyGetter<T> >&, const uint32_t&);
00045
00047 bool empty() const;
00048
00050 uint32_t size() const;
00051
00053 const RegionIndex<T>& operator[](uint32_t) const;
00054
00057 const RegionIndex<T>& back() const;
00058
00060 const_iterator begin() const;
00061
00063 const_iterator end() const;
00064
00066 bool find(uint32_t) const;
00067
00068 private:
00069
00070 collection_type sets_;
00071 std::vector<uint32_t> regions_;
00072 };
00073
00074 template <class T>
00075 inline
00076 RefGetter<T>::RefGetter(uint32_t maxindex) : sets_(), regions_(maxindex/32+1,0)
00077 {}
00078
00079 template <class T>
00080 inline
00081 RefGetter<T>::RefGetter(const edm::Handle<LazyGetter<T> >& getter, const std::vector<uint32_t>& interest) : sets_(), regions_(getter->regions()/32+1,0)
00082 {
00083 sets_.reserve(interest.size());
00084 for (uint32_t index=0;index<interest.size();index++) {
00085 sets_.push_back(region_ref(getter,interest[index],false));
00086 }
00087 }
00088
00089 template <class T>
00090 inline
00091 void
00092 RefGetter<T>::reserve(uint32_t size)
00093 {
00094 sets_.reserve(size);
00095 }
00096
00097 template <class T>
00098 inline
00099 void
00100 RefGetter<T>::swap(RefGetter<T>& other)
00101 {
00102 sets_.swap(other.sets_);
00103 regions_.swap(other.regions_);
00104 }
00105
00106 template <class T>
00107 inline
00108 void
00109 RefGetter<T>::push_back(const edm::Handle< LazyGetter<T> >& getter, const uint32_t& index)
00110 {
00111 sets_.push_back(region_ref(getter, index, false));
00112 regions_[index/32] = regions_[index/32]|(1<<index%32);
00113 }
00114
00115 template <class T>
00116 inline
00117 bool
00118 RefGetter<T>::empty() const
00119 {
00120 return sets_.empty();
00121 }
00122
00123 template <class T>
00124 inline
00125 uint32_t
00126 RefGetter<T>::size() const
00127 {
00128 return sets_.size();
00129 }
00130
00131 template <class T>
00132 inline
00133 const RegionIndex<T>&
00134 RefGetter<T>::operator[](uint32_t index) const
00135 {
00136 if (size() < index+1) edm::lazydetail::_throw_range(index);
00137 const_iterator it = sets_.begin()+index;
00138 return *it;
00139 }
00140
00141 template <class T>
00142 inline
00143 const RegionIndex<T>&
00144 RefGetter<T>::back() const
00145 {
00146 if (empty()) edm::lazydetail::_throw_range(0);
00147 return (*this)[size()-1];
00148 }
00149
00150 template <class T>
00151 inline
00152 typename RefGetter<T>::const_iterator
00153 RefGetter<T>::begin() const
00154 {
00155 return sets_.begin();
00156 }
00157
00158 template <class T>
00159 inline
00160 typename RefGetter<T>::const_iterator
00161 RefGetter<T>::end() const
00162 {
00163 return sets_.end();
00164 }
00165
00166 template <class T>
00167 inline
00168 bool
00169 RefGetter<T>::find(uint32_t index) const
00170 {
00171 return (regions_[index/32]>>(index%32))&1;
00172 }
00173
00174 template <class T>
00175 inline
00176 void
00177 swap(RefGetter<T>& a, RefGetter<T>& b)
00178 {
00179 a.swap(b);
00180 }
00181
00182
00183
00184 }
00185
00186 #endif
00187