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