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