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