00001 #ifndef DataFormats_Common_DetSetVectorNew_h
00002 #define DataFormats_Common_DetSetVectorNew_h
00003
00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00005
00006 #include "DataFormats/Common/interface/DetSetNew.h"
00007 #include "DataFormats/Common/interface/traits.h"
00008
00009 #include <boost/iterator_adaptors.hpp>
00010 #include <boost/iterator/transform_iterator.hpp>
00011 #include <boost/iterator/counting_iterator.hpp>
00012 #include <boost/any.hpp>
00013 #include "boost/shared_ptr.hpp"
00014
00015
00016 #include<vector>
00017
00018 namespace edm { namespace refhelper { template<typename T> struct FindForNewDetSetVector; } }
00019
00020
00021 namespace edmNew {
00022 typedef uint32_t det_id_type;
00023
00024 namespace dslv {
00025 template< typename T> class LazyGetter;
00026 }
00027
00028
00029
00030
00031 namespace dstvdetails {
00032 struct DetSetVectorTrans {
00033 DetSetVectorTrans(): filling(false){}
00034 bool filling;
00035 boost::any getter;
00036
00037 typedef unsigned int size_type;
00038 typedef unsigned int id_type;
00039
00040 struct Item {
00041 Item(id_type i=0, int io=-1, size_type is=0) : id(i), offset(io), size(is){}
00042 id_type id;
00043 int offset;
00044 size_type size;
00045 bool operator<(Item const &rh) const { return id<rh.id;}
00046 operator id_type() const { return id;}
00047 };
00048
00049 };
00050 void errorFilling();
00051 void errorIdExists(det_id_type iid);
00052 void throw_range(det_id_type iid);
00053 }
00054
00065 template<typename T>
00066 class DetSetVector : private dstvdetails::DetSetVectorTrans {
00067 public:
00068 typedef dstvdetails::DetSetVectorTrans Trans;
00069 typedef Trans::Item Item;
00070 typedef unsigned int size_type;
00071 typedef unsigned int id_type;
00072 typedef T data_type;
00073 typedef edmNew::DetSetVector<T> self;
00074 typedef edmNew::DetSet<T> DetSet;
00075 typedef dslv::LazyGetter<T> Getter;
00076
00077 typedef DetSet value_type;
00078 typedef id_type key_type;
00079
00080
00081 typedef std::vector<Item> IdContainer;
00082 typedef std::vector<data_type> DataContainer;
00083 typedef typename IdContainer::iterator IdIter;
00084 typedef typename std::vector<data_type>::iterator DataIter;
00085 typedef std::pair<IdIter,DataIter> IterPair;
00086 typedef typename IdContainer::const_iterator const_IdIter;
00087 typedef typename std::vector<data_type>::const_iterator const_DataIter;
00088 typedef std::pair<const_IdIter,const_DataIter> const_IterPair;
00089
00090 typedef typename edm::refhelper::FindForNewDetSetVector<data_type> RefFinder;
00091
00092 struct IterHelp {
00093 typedef DetSet result_type;
00094 IterHelp() : v(0){}
00095 IterHelp(DetSetVector<T> const & iv) : v(&iv){}
00096
00097 result_type & operator()(Item const& item) const {
00098 detset.set(*v,item);
00099 return detset;
00100 }
00101 private:
00102 DetSetVector<T> const * v;
00103 mutable result_type detset;
00104 };
00105
00106 typedef boost::transform_iterator<IterHelp,const_IdIter> const_iterator;
00107 typedef std::pair<const_iterator,const_iterator> Range;
00108
00109
00110
00111 class FastFiller {
00112 public:
00113 typedef typename DetSetVector<T>::data_type value_type;
00114 typedef typename DetSetVector<T>::id_type key_type;
00115 typedef typename DetSetVector<T>::id_type id_type;
00116 typedef typename DetSetVector<T>::size_type size_type;
00117
00118 FastFiller(DetSetVector<T> & iv, id_type id, bool isaveEmpty=false) :
00119 v(iv), item(v.push_back(id)), saveEmpty(isaveEmpty) {
00120 if (v.filling) dstvdetails::errorFilling();
00121 v.filling=true;
00122 }
00123 FastFiller(DetSetVector<T> & iv, typename DetSetVector<T>::Item & it, bool isaveEmpty=false) :
00124 v(iv), item(it), saveEmpty(isaveEmpty) {
00125 if (v.filling) dstvdetails::errorFilling();
00126 v.filling=true;
00127 }
00128 ~FastFiller() {
00129 if (!saveEmpty && item.size==0) {
00130 v.pop_back(item.id);
00131 }
00132 v.filling=false;
00133 }
00134
00135 void abort() {
00136 v.pop_back(item.id);
00137 saveEmpty=true;
00138 }
00139
00140 void reserve(size_type s) {
00141 v.m_data.reserve(item.offset+s);
00142 }
00143
00144 void resize(size_type s) {
00145 v.m_data.resize(item.offset+s);
00146 item.size=s;
00147 }
00148
00149 id_type id() const { return item.id;}
00150 size_type size() const { return item.size;}
00151 bool empty() const { return item.size==0;}
00152
00153 data_type & operator[](size_type i) {
00154 return v.m_data[item.offset+i];
00155 }
00156 DataIter begin() { return v.m_data.begin()+ item.offset;}
00157 DataIter end() { return v.m_data.end();}
00158
00159 void push_back(data_type const & d) {
00160 v.m_data.push_back(d);
00161 item.size++;
00162 }
00163 data_type & back() { return v.m_data.back();}
00164
00165 private:
00166 DetSetVector<T> & v;
00167 typename DetSetVector<T>::Item & item;
00168 bool saveEmpty;
00169 };
00170 friend class FastFiller;
00171
00172 class FindForDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, const T*> {
00173 public:
00174 typedef FindForDetSetVector self;
00175 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00176 return &(iContainer.m_data[iIndex]);
00177 }
00178 };
00179 friend class FindForDetSetVector;
00180
00181 explicit DetSetVector(int isubdet=0) :
00182 m_subdetId(isubdet) {}
00183
00184 DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter, const std::vector<det_id_type>& iDets,
00185 int isubdet=0);
00186
00187
00188 ~DetSetVector() {
00189
00190 }
00191
00192 void swap(DetSetVector & rh) {
00193 std::swap(m_subdetId,rh.m_subdetId);
00194 std::swap(m_ids,rh.m_ids);
00195 std::swap(m_data,rh.m_data);
00196 }
00197
00198 void swap(IdContainer & iic, DataContainer & idc) {
00199 std::swap(m_ids,iic);
00200 std::swap(m_data,idc);
00201 }
00202
00203 void reserve(size_t isize, size_t dsize) {
00204 m_ids.reserve(isize);
00205 m_data.reserve(dsize);
00206 }
00207
00208 void resize(size_t isize, size_t dsize) {
00209 m_ids.resize(isize);
00210 m_data.resize(dsize);
00211 }
00212
00213
00214 DetSet insert(id_type iid, data_type const * idata, size_type isize) {
00215 Item & item = addItem(iid,isize);
00216 m_data.resize(m_data.size()+isize);
00217 std::copy(idata,idata+isize,m_data.begin()+item.offset);
00218 return DetSet(*this,item);
00219 }
00220
00221 DetSet insert(id_type iid, size_type isize) {
00222 Item & item = addItem(iid,isize);
00223 m_data.resize(m_data.size()+isize);
00224 return DetSet(*this,item);
00225 }
00226
00227
00228 Item & push_back(id_type iid) {
00229 return addItem(iid,0);
00230 }
00231
00232
00233 void pop_back(id_type iid) {
00234 const_IdIter p = findItem(iid);
00235 if (p==m_ids.end()) return;
00236
00237 if ((*p).size>0&& (*p).offset>-1 &&
00238 m_data.size()==(*p).offset+(*p).size)
00239 m_data.resize((*p).offset);
00240 m_ids.erase( m_ids.begin()+(p-m_ids.begin()));
00241 }
00242
00243 private:
00244
00245 Item & addItem(id_type iid, size_type isize) {
00246 Item it(iid,size_type(m_data.size()),isize);
00247 IdIter p = std::lower_bound(m_ids.begin(),
00248 m_ids.end(),
00249 it);
00250 if (p!=m_ids.end() && !(it<*p)) dstvdetails::errorIdExists(iid);
00251 return *m_ids.insert(p,it);
00252 }
00253
00254
00255
00256 public:
00257
00258
00259
00260
00261 bool exists(id_type i) const {
00262 return findItem(i)!=m_ids.end();
00263 }
00264
00265 bool isValid(id_type i) const {
00266 const_IdIter p = findItem(i);
00267 return p!=m_ids.end() && (*p).offset!=-1;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 DetSet operator[](id_type i) const {
00280 const_IdIter p = findItem(i);
00281 if (p==m_ids.end()) dstvdetails::throw_range(i);
00282 return DetSet(*this,*p);
00283 }
00284
00285
00286 const_iterator find(id_type i) const {
00287 const_IdIter p = findItem(i);
00288 return (p==m_ids.end()) ? end() :
00289 boost::make_transform_iterator(p,
00290 IterHelp(*this));
00291 }
00292
00293
00294 const_IdIter findItem(id_type i) const {
00295 std::pair<const_IdIter,const_IdIter> p =
00296 std::equal_range(m_ids.begin(),m_ids.end(),Item(i));
00297 return (p.first!=p.second) ? p.first : m_ids.end();
00298 }
00299
00300 const_iterator begin() const {
00301 return boost::make_transform_iterator(m_ids.begin(),
00302 IterHelp(*this));
00303 }
00304
00305 const_iterator end() const {
00306 return boost::make_transform_iterator(m_ids.end(),
00307 IterHelp(*this));
00308 }
00309
00310
00311
00312 template<typename CMP>
00313 Range equal_range(id_type i, CMP cmp) const {
00314 std::pair<const_IdIter,const_IdIter> p =
00315 std::equal_range(m_ids.begin(),m_ids.end(),i,cmp);
00316 return Range(boost::make_transform_iterator(p.first,IterHelp(*this)),
00317 boost::make_transform_iterator(p.second,IterHelp(*this))
00318 );
00319 }
00320
00321 int subdetId() const { return m_subdetId; }
00322
00323 bool empty() const { return m_ids.empty();}
00324
00325
00326 size_type dataSize() const { return m_data.size(); }
00327
00328 size_type size() const { return m_ids.size();}
00329
00330
00331
00332 data_type operator()(size_t cell, size_t frame) const {
00333 return m_data[m_ids[cell].offset+frame];
00334 }
00335
00336 data_type const * data(size_t cell) const {
00337 return &m_data[m_ids[cell].offset];
00338 }
00339
00340 size_type detsetSize(size_t cell) const { return m_ids[cell].size; }
00341
00342 id_type id(size_t cell) const {
00343 return m_ids[cell].id;
00344 }
00345
00346 Item const & item(size_t cell) const {
00347 return m_ids[cell];
00348 }
00349
00350
00351
00352
00353 DataContainer const & data() const { return m_data;}
00354
00355
00356 void update(Item const & item) const {
00357 const_cast<self*>(this)->updateImpl(const_cast<Item&>(item));
00358 }
00359
00360
00361 CMS_CLASS_VERSION(10)
00362
00363 private:
00364
00365 void updateImpl(Item & item);
00366
00367 private:
00368
00369 int m_subdetId;
00370
00371
00372 IdContainer m_ids;
00373 DataContainer m_data;
00374
00375 };
00376
00377 namespace dslv {
00378 template< typename T>
00379 class LazyGetter {
00380 public:
00381 virtual ~LazyGetter() {}
00382 virtual void fill(typename DetSetVector<T>::FastFiller&) = 0;
00383 };
00384 }
00385
00386
00387
00388 template<typename T>
00389 inline DetSetVector<T>::DetSetVector(boost::shared_ptr<dslv::LazyGetter<T> > iGetter,
00390 const std::vector<det_id_type>& iDets,
00391 int isubdet):
00392 m_subdetId(isubdet) {
00393 getter=iGetter;
00394
00395 m_ids.reserve(iDets.size());
00396 det_id_type sanityCheck = 0;
00397 for(std::vector<det_id_type>::const_iterator itDetId = iDets.begin(), itDetIdEnd = iDets.end();
00398 itDetId != itDetIdEnd;
00399 ++itDetId) {
00400 assert(sanityCheck < *itDetId && "vector of det_id_type was not ordered");
00401 sanityCheck = *itDetId;
00402 m_ids.push_back(*itDetId);
00403 }
00404 }
00405
00406 template<typename T>
00407 inline void DetSetVector<T>::updateImpl(Item & item) {
00408
00409 if (getter.empty() || item.offset!=-1) return;
00410 item.offset = int(m_data.size());
00411 FastFiller ff(*this,item);
00412 (*boost::any_cast<boost::shared_ptr<Getter> >(&getter))->fill(ff);
00413 }
00414
00415
00416 template<typename T>
00417 inline DetSet<T>::DetSet(DetSetVector<T> const & icont,
00418 typename DetSetVector<T>::Item const & item ) :
00419 m_id(0), m_data(0), m_size(0){
00420 icont.update(item);
00421 set(icont,item);
00422 }
00423
00424
00425 template<typename T>
00426 inline void DetSet<T>::set(DetSetVector<T> const & icont,
00427 typename Container::Item const & item) {
00428 icont.update(item);
00429 m_id=item.id;
00430 m_data=&icont.data()[item.offset];
00431 m_size=item.size;
00432 }
00433
00434 }
00435
00436 #include "DataFormats/Common/interface/Ref.h"
00437 #include <boost/mpl/assert.hpp>
00438 #include <boost/type_traits/is_same.hpp>
00439
00440
00441 namespace edm {
00442
00443 namespace refhelper {
00444 template<typename T>
00445 struct FindTrait<typename edmNew::DetSetVector<T>,T> {
00446 typedef typename edmNew::DetSetVector<T>::FindForDetSetVector value;
00447 };
00448 }
00449
00450
00451
00452 namespace refhelper {
00453 template<typename T>
00454 struct FindSetForNewDetSetVector : public std::binary_function<const edmNew::DetSetVector<T>&, unsigned int, edmNew::DetSet<T> > {
00455 typedef FindSetForNewDetSetVector<T> self;
00456 typename self::result_type operator()(typename self::first_argument_type iContainer, typename self::second_argument_type iIndex) {
00457 return &(iContainer[iIndex]);
00458 }
00459 };
00460
00461 template<typename T>
00462 struct FindTrait<edmNew::DetSetVector<T>, edmNew::DetSet<T> > {
00463 typedef FindSetForNewDetSetVector<T> value;
00464 };
00465 }
00466
00467 }
00468
00469 namespace edmNew {
00470
00471 template<class HandleT>
00472 edm::Ref<typename HandleT::element_type, typename HandleT::element_type::value_type::value_type>
00473 makeRefTo(const HandleT& iHandle,
00474 typename HandleT::element_type::value_type::const_iterator itIter) {
00475 BOOST_MPL_ASSERT((boost::is_same<typename HandleT::element_type, DetSetVector<typename HandleT::element_type::value_type::value_type> >));
00476 typename HandleT::element_type::size_type index = (itIter - &*iHandle->data().begin());
00477 return edm::Ref<typename HandleT::element_type,
00478 typename HandleT::element_type::value_type::value_type>
00479 (iHandle,index);
00480 }
00481 }
00482
00483
00484 #endif
00485