Logo ROOT   6.12/07
Reference Guide
TCollectionProxyInfo.h
Go to the documentation of this file.
1 // @(#)root/cont:$Id$
2 // Author: Markus Frank 28/10/04. Philippe Canal 02/01/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TCollectionProxyInfo
13 #define ROOT_TCollectionProxyInfo
14 
15 //////////////////////////////////////////////////////////////////////////
16 // //
17 // Small helper to gather the information neede to generate a //
18 // Collection Proxy //
19 //
20 //////////////////////////////////////////////////////////////////////////
21 
22 #include "TError.h"
23 #include <vector>
24 #include <forward_list>
25 
26 #if defined(_WIN32)
27  #if _MSC_VER<1300
28  #define TYPENAME
29  #define R__VCXX6
30  #else
31  #define TYPENAME typename
32  #endif
33 #else
34  #define TYPENAME typename
35 #endif
36 
37 namespace ROOT {
38 
39 namespace Internal {
40 template <typename T> class TStdBitsetHelper {
41  // This class is intentionally empty, this is scaffolding to allow the equivalent
42  // of 'template <int N> struct TCollectionProxyInfo::Type<std::bitset<N> >' which
43  // is not effective in C++ (as of gcc 4.3.3).
44 };
45 }
46 
47 namespace Detail {
49  // This class is a place holder for the information needed
50  // to create the proper Collection Proxy.
51  // This is similar to Reflex's CollFuncTable.
52 
53  public:
54 
55  // Same value as TVirtualCollectionProxy.
56  static const UInt_t fgIteratorArenaSize = 16; // greater than sizeof(void*) + sizeof(UInt_t)
57 
58  /** @class ROOT::Detail::TCollectionProxyInfo::IteratorValue
59  *
60  * Small helper to encapsulate whether to return the value
61  * pointed to by the iterator or its address.
62  *
63  **/
64 
65  template <typename Cont_t, typename value> struct IteratorValue {
66  static void* get(typename Cont_t::iterator &iter) {
67  return (void*)&(*iter);
68  }
69  };
70 
71  template <typename Cont_t, typename value_ptr> struct IteratorValue<Cont_t, value_ptr*> {
72  static void* get(typename Cont_t::iterator &iter) {
73  return (void*)(*iter);
74  }
75  };
76 
77  /** @class ROOT::Detail::TCollectionProxyInfo::Iterators
78  *
79  * Small helper to implement the function to create,access and destroy
80  * iterators.
81  *
82  **/
83 
84  template <typename Cont_t, bool large = false>
85  struct Iterators {
86  typedef Cont_t *PCont_t;
87  typedef typename Cont_t::iterator iterator;
88 
89  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
90  PCont_t c = PCont_t(coll);
91  new (*begin_arena) iterator(c->begin());
92  new (*end_arena) iterator(c->end());
93  }
94  static void* copy(void *dest_arena, const void *source_ptr) {
95  iterator *source = (iterator *)(source_ptr);
96  new (dest_arena) iterator(*source);
97  return dest_arena;
98  }
99  static void* next(void *iter_loc, const void *end_loc) {
100  iterator *end = (iterator *)(end_loc);
101  iterator *iter = (iterator *)(iter_loc);
102  if (*iter != *end) {
104  ++(*iter);
105  return result;
106  }
107  return 0;
108  }
109  static void destruct1(void *iter_ptr) {
110  iterator *start = (iterator *)(iter_ptr);
111  start->~iterator();
112  }
113  static void destruct2(void *begin_ptr, void *end_ptr) {
114  iterator *start = (iterator *)(begin_ptr);
115  iterator *end = (iterator *)(end_ptr);
116  start->~iterator();
117  end->~iterator();
118  }
119  };
120 
121  // For Vector we take an extra short cut to avoid derefencing
122  // the iterator all the time and redefine the 'address' of the
123  // iterator as the iterator itself. This requires special handling
124  // in the looper (see TStreamerInfoAction) but is much faster.
125  template <typename T> struct Iterators<std::vector<T>, false> {
126  typedef std::vector<T> Cont_t;
127  typedef Cont_t *PCont_t;
128  typedef typename Cont_t::iterator iterator;
129 
130  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
131  PCont_t c = PCont_t(coll);
132  if (c->empty()) {
133  *begin_arena = 0;
134  *end_arena = 0;
135  return;
136  }
137  *begin_arena = &(*c->begin());
138 #ifdef R__VISUAL_CPLUSPLUS
139  *end_arena = &(*(c->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
140 #else
141  // coverity[past_the_end] Safe on other platforms
142  *end_arena = &(*c->end());
143 #endif
144  }
145  static void* copy(void *dest, const void *source) {
146  *(void**)dest = *(void**)(const_cast<void*>(source));
147  return dest;
148  }
149  static void* next(void * /* iter_loc */, const void * /* end_loc */) {
150  // Should not be used.
151  // In the case of vector, so that the I/O can perform better,
152  // the begin_arena and the end_arena are *not* set to the
153  // address of any iterator rather they are set to the value of
154  // the beginning (and end) address of the vector's data.
155  // Hence this routine (which takes the value of fBegin) can
156  // *not* update where its points to (which in the case of vector
157  // would require update the value of fBegin).
158  R__ASSERT(0 && "Intentionally not implemented, do not use.");
159  return 0;
160  }
161  static void destruct1(void * /* iter_ptr */) {
162  // Nothing to do
163  }
164  static void destruct2(void * /* begin_ptr */, void * /* end_ptr */) {
165  // Nothing to do
166  }
167  };
168 
169  template <typename Cont_t> struct Iterators<Cont_t, /* large= */ true > {
170  typedef Cont_t *PCont_t;
171  typedef typename Cont_t::iterator iterator;
172 
173  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
174  PCont_t c = PCont_t(coll);
175  *begin_arena = new iterator(c->begin());
176  *end_arena = new iterator(c->end());
177  }
178  static void* copy(void * /*dest_arena*/, const void *source_ptr) {
179  iterator *source = (iterator *)(source_ptr);
180  void *iter = new iterator(*source);
181  return iter;
182  }
183  static void* next(void *iter_loc, const void *end_loc) {
184  iterator *end = (iterator *)(end_loc);
185  iterator *iter = (iterator *)(iter_loc);
186  if (*iter != *end) {
188  ++(*iter);
189  return result;
190  }
191  return 0;
192  }
193  static void destruct1(void *begin_ptr) {
194  iterator *start = (iterator *)(begin_ptr);
195  delete start;
196  }
197  static void destruct2(void *begin_ptr, void *end_ptr) {
198  iterator *start = (iterator *)(begin_ptr);
199  iterator *end = (iterator *)(end_ptr);
200  delete start;
201  delete end;
202  }
203  };
204 
205  /** @class ROOT::Detail::TCollectionProxyInfo::Environ
206  *
207  * Small helper to save proxy environment in the event of
208  * recursive calls.
209  *
210  * @author M.Frank
211  * @version 1.0
212  * @date 10/10/2004
213  */
214  struct EnvironBase {
215  private:
216  EnvironBase(const EnvironBase&); // Intentionally not implement, copy is not supported
217  EnvironBase &operator=(const EnvironBase&); // Intentionally not implement, copy is not supported
218  public:
219  EnvironBase() : fIdx(0), fSize(0), fObject(0), fStart(0), fTemp(0), fUseTemp(kFALSE), fRefCount(1), fSpace(0)
220  {
221  }
222  virtual ~EnvironBase() {}
223  size_t fIdx;
224  size_t fSize;
225  void* fObject;
226  void* fStart;
227  void* fTemp;
228  union {
231  };
233  size_t fSpace;
234  };
235  template <typename T> struct Environ : public EnvironBase {
236  Environ() : fIterator() {}
237  typedef T Iter_t;
238  Iter_t fIterator;
239  T& iter() { return fIterator; }
240  static void *Create() {
241  return new Environ();
242  }
243  };
244 
245  template <class T, class Q> struct PairHolder {
249  PairHolder(const PairHolder& c) : first(c.first), second(c.second) {}
250  virtual ~PairHolder() {}
251  private:
252  PairHolder& operator=(const PairHolder&); // not implemented
253  };
254 
255  template <class T> struct Address {
256  virtual ~Address() {}
257  static void* address(T ref) {
258  return const_cast<void*>(reinterpret_cast<const void*>(&ref));
259  }
260  };
261 
262  struct SfinaeHelper {
263  // Use SFINAE to get the size of the container
264 
265  // In general we get the size of the container with the size method
266  template <class T>
267  static size_t GetContainerSize(const T& c) {return c.size();}
268 
269  // Since forward_list does not provide a size operator, we have to
270  // use an alternative. This has a cost of course.
271  template <class T, class ALLOCATOR>
272  static size_t GetContainerSize(const std::forward_list<T,ALLOCATOR>& c) {return std::distance(c.begin(),c.end());}
273  };
274 
275  /** @class ROOT::Detail::TCollectionProxyInfo::Type
276  *
277  * Small helper to encapsulate basic data accesses for
278  * all STL continers.
279  *
280  * @author M.Frank
281  * @version 1.0
282  * @date 10/10/2004
283  */
284  template <class T> struct Type
285  : public Address<TYPENAME T::const_reference>
286  {
287  typedef T Cont_t;
288  typedef typename T::iterator Iter_t;
289  typedef typename T::value_type Value_t;
291  typedef Env_t *PEnv_t;
292  typedef Cont_t *PCont_t;
293  typedef Value_t *PValue_t;
294 
295  virtual ~Type() {}
296 
297  static inline PCont_t object(void* ptr) {
298  return PCont_t(PEnv_t(ptr)->fObject);
299  }
300  static void* size(void* env) {
301  PEnv_t e = PEnv_t(env);
302  e->fSize = SfinaeHelper::GetContainerSize(*PCont_t(e->fObject));
303  return &e->fSize;
304  }
305  static void* clear(void* env) {
306  object(env)->clear();
307  return 0;
308  }
309  static void* first(void* env) {
310  PEnv_t e = PEnv_t(env);
311  PCont_t c = PCont_t(e->fObject);
312 #if 0
313  // Assume iterators do not need destruction
314  ::new(e->buff) Iter_t(c->begin());
315 #endif
316  e->fIterator = c->begin();
317  e->fSize = SfinaeHelper::GetContainerSize(*c);
318  if ( 0 == e->fSize ) return e->fStart = 0;
319  TYPENAME T::const_reference ref = *(e->iter());
320  return e->fStart = Type<T>::address(ref);
321  }
322  static void* next(void* env) {
323  PEnv_t e = PEnv_t(env);
324  PCont_t c = PCont_t(e->fObject);
325  for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
326  // TODO: Need to find something for going backwards....
327  if ( e->iter() == c->end() ) return 0;
328  TYPENAME T::const_reference ref = *(e->iter());
329  return Type<T>::address(ref);
330  }
331  static void* construct(void *what, size_t size) {
332  PValue_t m = PValue_t(what);
333  for (size_t i=0; i<size; ++i, ++m)
334  ::new(m) Value_t();
335  return 0;
336  }
337  static void* collect(void *coll, void *array) {
338  PCont_t c = PCont_t(coll);
339  PValue_t m = PValue_t(array);
340  for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
341  ::new(m) Value_t(*i);
342  return 0;
343  }
344  static void destruct(void *what, size_t size) {
345  PValue_t m = PValue_t(what);
346  for (size_t i=0; i < size; ++i, ++m )
347  m->~Value_t();
348  }
349 
350  static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
352 
353  };
354 
355  /** @class ROOT::Detail::TCollectionProxyInfo::Pushback
356  *
357  * Small helper to encapsulate all necessary data accesses for
358  * containers like vector, list, deque
359  *
360  * @author M.Frank
361  * @version 1.0
362  * @date 10/10/2004
363  */
364  template <class T> struct Pushback : public Type<T> {
365  typedef T Cont_t;
366  typedef typename T::iterator Iter_t;
367  typedef typename T::value_type Value_t;
369  typedef Env_t *PEnv_t;
370  typedef Cont_t *PCont_t;
371  typedef Value_t *PValue_t;
372  static void resize(void* obj, size_t n) {
373  PCont_t c = PCont_t(obj);
374  c->resize(n);
375  }
376  static void* feed(void *from, void *to, size_t size) {
377  PCont_t c = PCont_t(to);
378  PValue_t m = PValue_t(from);
379  for (size_t i=0; i<size; ++i, ++m)
380  c->push_back(*m);
381  return 0;
382  }
383  static int value_offset() {
384  return 0;
385  }
386  };
387 
388  /** @class ROOT::Detail::TCollectionProxyInfo::Pushfront
389  *
390  * Small helper to encapsulate all necessary data accesses for
391  * containers like forward_list
392  *
393  * @author D.Piparo
394  * @version 1.0
395  * @date 26/02/2015
396  */
397  template <class T> struct Pushfront : public Type<T> {
398  typedef T Cont_t;
399  typedef typename T::iterator Iter_t;
400  typedef typename T::value_type Value_t;
402  typedef Env_t *PEnv_t;
403  typedef Cont_t *PCont_t;
404  typedef Value_t *PValue_t;
405  static void resize(void* obj, size_t n) {
406  PCont_t c = PCont_t(obj);
407  c->resize(n);
408  }
409  static void* feed(void *from, void *to, size_t size) {
410  PCont_t c = PCont_t(to);
411  if (size==0) return 0;
412  PValue_t m = &(PValue_t(from)[size-1]); // Take the last item
413  // Iterate backwards not to revert ordering
414  for (size_t i=0; i<size; ++i, --m){
415  c->push_front(*m);
416  }
417  return 0;
418  }
419  static int value_offset() {
420  return 0;
421  }
422  };
423 
424  /** @class ROOT::Detail::TCollectionProxyInfo::Insert
425  *
426  * Small helper to encapsulate all necessary data accesses for
427  * containers like set, multiset etc.
428  *
429  * @author M.Frank
430  * @version 1.0
431  * @date 10/10/2004
432  */
433  template <class T> struct Insert : public Type<T> {
434  typedef T Cont_t;
435  typedef typename T::iterator Iter_t;
436  typedef typename T::value_type Value_t;
438  typedef Env_t *PEnv_t;
439  typedef Cont_t *PCont_t;
440  typedef Value_t *PValue_t;
441  static void* feed(void *from, void *to, size_t size) {
442  PCont_t c = PCont_t(to);
443  PValue_t m = PValue_t(from);
444  for (size_t i=0; i<size; ++i, ++m)
445  c->insert(*m);
446  return 0;
447  }
448  static void resize(void* /* obj */, size_t ) {
449  ;
450  }
451  static int value_offset() {
452  return 0;
453  }
454  };
455 
456  /** @class ROOT::Detail::TCollectionProxyInfo::MapInsert
457  *
458  * Small helper to encapsulate all necessary data accesses for
459  * containers like set, multiset etc.
460  *
461  * @author M.Frank
462  * @version 1.0
463  * @date 10/10/2004
464  */
465  template <class T> struct MapInsert : public Type<T> {
466  typedef T Cont_t;
467  typedef typename T::iterator Iter_t;
468  typedef typename T::value_type Value_t;
470  typedef Env_t *PEnv_t;
471  typedef Cont_t *PCont_t;
472  typedef Value_t *PValue_t;
473  static void* feed(void *from, void *to, size_t size) {
474  PCont_t c = PCont_t(to);
475  PValue_t m = PValue_t(from);
476  for (size_t i=0; i<size; ++i, ++m)
477  c->insert(*m);
478  return 0;
479  }
480  static void resize(void* /* obj */, size_t ) {
481  ;
482  }
483  static int value_offset() {
484  return ((char*)&((PValue_t(0x1000))->second)) - ((char*)PValue_t(0x1000));
485  }
486  };
487 
488 
489  public:
490  const std::type_info &fInfo;
491  size_t fIterSize;
492  size_t fValueDiff;
494  void* (*fSizeFunc)(void*);
495  void (*fResizeFunc)(void*,size_t);
496  void* (*fClearFunc)(void*);
497  void* (*fFirstFunc)(void*);
498  void* (*fNextFunc)(void*);
499  void* (*fConstructFunc)(void*,size_t);
500  void (*fDestructFunc)(void*,size_t);
501  void* (*fFeedFunc)(void*,void*,size_t);
502  void* (*fCollectFunc)(void*,void*);
503  void* (*fCreateEnv)();
504 
505  // Set of function of direct iteration of the collections.
506  void (*fCreateIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy);
507  // begin_arena and end_arena should contain the location of memory arena of size fgIteratorSize.
508  // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
509  // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
510 
511  void* (*fCopyIterator)(void *dest, const void *source);
512  // Copy the iterator source, into dest. dest should contain should contain the location of memory arena of size fgIteratorSize.
513  // If the collection iterator are of that size or less, the iterator will be constructed in place in this location (new with placement)
514  // Otherwise the iterator will be allocated via a regular new and its address returned by modifying the value of dest.
515 
516  void* (*fNext)(void *iter, const void *end);
517  // iter and end should be pointer to respectively an iterator to be incremented and the result of colleciton.end()
518  // 'Next' will increment the iterator 'iter' and return 0 if the iterator reached the end.
519  // If the end is not reached, 'Next' will return the address of the content unless the collection contains pointers in
520  // which case 'Next' will return the value of the pointer.
521 
522  void (*fDeleteSingleIterator)(void *iter);
523  void (*fDeleteTwoIterators)(void *begin, void *end);
524  // If the sizeof iterator is greater than fgIteratorArenaSize, call delete on the addresses,
525  // Otherwise just call the iterator's destructor.
526 
527  public:
528  TCollectionProxyInfo(const std::type_info& info,
529  size_t iter_size,
530  size_t value_diff,
531  int value_offset,
532  void* (*size_func)(void*),
533  void (*resize_func)(void*,size_t),
534  void* (*clear_func)(void*),
535  void* (*first_func)(void*),
536  void* (*next_func)(void*),
537  void* (*construct_func)(void*,size_t),
538  void (*destruct_func)(void*,size_t),
539  void* (*feed_func)(void*,void*,size_t),
540  void* (*collect_func)(void*,void*),
541  void* (*create_env)(),
542  void (*getIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy) = 0,
543  void* (*copyIterator)(void *dest, const void *source) = 0,
544  void* (*next)(void *iter, const void *end) = 0,
545  void (*deleteSingleIterator)(void *iter) = 0,
546  void (*deleteTwoIterators)(void *begin, void *end) = 0
547  ) :
548  fInfo(info), fIterSize(iter_size), fValueDiff(value_diff),
549  fValueOffset(value_offset),
550  fSizeFunc(size_func),fResizeFunc(resize_func),fClearFunc(clear_func),
551  fFirstFunc(first_func),fNextFunc(next_func),fConstructFunc(construct_func),
552  fDestructFunc(destruct_func),fFeedFunc(feed_func),fCollectFunc(collect_func),
553  fCreateEnv(create_env),
554  fCreateIterators(getIterators),fCopyIterator(copyIterator),fNext(next),
555  fDeleteSingleIterator(deleteSingleIterator),fDeleteTwoIterators(deleteTwoIterators)
556  {
557  }
558 
559  /// Generate proxy from template
560  template <class T> static TCollectionProxyInfo* Generate(const T&) {
561  // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
562  // template (used to described the behavior of the stl collection.
563  // Typical use looks like:
564  // ::ROOT::Detail::TCollectionProxyInfo::Generate(TCollectionProxyInfo::Pushback< std::vector<string> >()));
565 
568  return new TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
569  sizeof(TYPENAME T::Iter_t),
570  (((char*)&p->second)-((char*)&p->first)),
571  T::value_offset(),
572  T::size,
573  T::resize,
574  T::clear,
575  T::first,
576  T::next,
577  T::construct,
578  T::destruct,
579  T::feed,
580  T::collect,
581  T::Env_t::Create,
582  T::Iterators_t::create,
583  T::Iterators_t::copy,
584  T::Iterators_t::next,
585  T::Iterators_t::destruct1,
586  T::Iterators_t::destruct2);
587  }
588 
589  template <class T> static TCollectionProxyInfo Get(const T&) {
590 
591  // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
592  // template (used to described the behavior of the stl collection.
593  // Typical use looks like:
594  // ::ROOT::Detail::TCollectionProxyInfo::Get(TCollectionProxyInfo::Pushback< std::vector<string> >()));
595 
598  return TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
599  sizeof(TYPENAME T::Iter_t),
600  (((char*)&p->second)-((char*)&p->first)),
601  T::value_offset(),
602  T::size,
603  T::resize,
604  T::clear,
605  T::first,
606  T::next,
607  T::construct,
608  T::destruct,
609  T::feed,
610  T::collect,
611  T::Env_t::Create);
612  }
613 
614  };
615 
616  template <> struct TCollectionProxyInfo::Type<std::vector<Bool_t> >
617  : public TCollectionProxyInfo::Address<std::vector<Bool_t>::const_reference>
618  {
619  typedef std::vector<Bool_t> Cont_t;
620  typedef std::vector<Bool_t>::iterator Iter_t;
621  typedef std::vector<Bool_t>::value_type Value_t;
623  typedef Env_t *PEnv_t;
624  typedef Cont_t *PCont_t;
625  typedef Value_t *PValue_t;
626 
627  virtual ~Type() {}
628 
629  static inline PCont_t object(void* ptr) {
630  return PCont_t(PEnv_t(ptr)->fObject);
631  }
632  static void* size(void* env) {
633  PEnv_t e = PEnv_t(env);
634  e->fSize = PCont_t(e->fObject)->size();
635  return &e->fSize;
636  }
637  static void* clear(void* env) {
638  object(env)->clear();
639  return 0;
640  }
641  static void* first(void* env) {
642  PEnv_t e = PEnv_t(env);
643  PCont_t c = PCont_t(e->fObject);
644 #if 0
645  // Assume iterators do not need destruction
646  ::new(e->buff) Iter_t(c->begin());
647 #endif
648  e->fIterator = c->begin();
649  e->fSize = c->size();
650  return 0;
651  }
652  static void* next(void* env) {
653  PEnv_t e = PEnv_t(env);
654  PCont_t c = PCont_t(e->fObject);
655  for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
656  // TODO: Need to find something for going backwards....
657  return 0;
658  }
659  static void* construct(void*,size_t) {
660  // Nothing to construct.
661  return 0;
662  }
663  static void* collect(void *coll, void *array) {
664  PCont_t c = PCont_t(coll);
665  PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
666  for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
667  ::new(m) Value_t(*i);
668  return 0;
669  }
670  static void destruct(void*,size_t) {
671  // Nothing to destruct.
672  }
673 
674  //static const bool fgLargeIterator = sizeof(Cont_t::iterator) > fgIteratorArenaSize;
675  //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
676 
677  struct Iterators {
678  typedef Cont_t::iterator iterator;
679 
680  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
681  PCont_t c = PCont_t(coll);
682  new (*begin_arena) iterator(c->begin());
683  new (*end_arena) iterator(c->end());
684  }
685  static void* copy(void *dest_arena, const void *source_ptr) {
686  const iterator *source = (const iterator *)(source_ptr);
687  new (dest_arena) iterator(*source);
688  return dest_arena;
689  }
690  static void* next(void *iter_loc, const void *end_loc) {
691  const iterator *end = (const iterator *)(end_loc);
692  iterator *iter = (iterator *)(iter_loc);
693  if (*iter != *end) {
694  ++(*iter);
695  //if (*iter != *end) {
696  // return IteratorValue<Cont_t, Cont_t::value_type>::get(*iter);
697  //}
698  }
699  return 0;
700  }
701  static void destruct1(void *iter_ptr) {
702  iterator *start = (iterator *)(iter_ptr);
703  start->~iterator();
704  }
705  static void destruct2(void *begin_ptr, void *end_ptr) {
706  iterator *start = (iterator *)(begin_ptr);
707  iterator *end = (iterator *)(end_ptr);
708  start->~iterator();
709  end->~iterator();
710  }
711  };
713 
714  };
715 
716  template <> struct TCollectionProxyInfo::Pushback<std::vector<bool> > : public TCollectionProxyInfo::Type<std::vector<Bool_t> > {
717  typedef std::vector<Bool_t> Cont_t;
718  typedef Cont_t::iterator Iter_t;
719  typedef Cont_t::value_type Value_t;
721  typedef Env_t *PEnv_t;
722  typedef Cont_t *PCont_t;
723  typedef Value_t *PValue_t;
724 
725  static void resize(void* obj,size_t n) {
726  PCont_t c = PCont_t(obj);
727  c->resize(n);
728  }
729  static void* feed(void* from, void *to, size_t size) {
730  PCont_t c = PCont_t(to);
731  PValue_t m = PValue_t(from);
732  for (size_t i=0; i<size; ++i, ++m)
733  c->push_back(*m);
734  return 0;
735  }
736  static int value_offset() {
737  return 0;
738  }
739  };
740 
741  // Need specialization for boolean references due to stupid STL std::vector<bool>
742  template<> inline void* TCollectionProxyInfo::Address<std::vector<Bool_t>::const_reference>::address(std::vector<Bool_t>::const_reference ) {
743  R__ASSERT(0);
744  return 0;
745  }
746 
747  template <typename Bitset_t> struct TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Address<const Bool_t &>
748  {
749  typedef Bitset_t Cont_t;
750  typedef std::pair<size_t,Bool_t> Iter_t;
751  typedef Bool_t Value_t;
753  typedef Env_t *PEnv_t;
754  typedef Cont_t *PCont_t;
755  typedef Value_t *PValue_t;
756 
757  virtual ~Type() {}
758 
759  static inline PCont_t object(void* ptr) {
760  return PCont_t(PEnv_t(ptr)->fObject);
761  }
762  static void* size(void* env) {
763  PEnv_t e = PEnv_t(env);
764  e->fSize = PCont_t(e->fObject)->size();
765  return &e->fSize;
766  }
767  static void* clear(void* env) {
768  object(env)->reset();
769  return 0;
770  }
771  static void* first(void* env) {
772  PEnv_t e = PEnv_t(env);
773  PCont_t c = PCont_t(e->fObject);
774  e->fIterator.first = 0;
775  e->fIterator.second = c->size() > 0 ? c->test(e->fIterator.first) : false ; // Iterator actually hold the value.
776  e->fSize = c->size();
777  return &(e->fIterator.second);
778  }
779  static void* next(void* env) {
780  PEnv_t e = PEnv_t(env);
781  PCont_t c = PCont_t(e->fObject);
782  for (; e->fIdx > 0 && e->fIterator.first != c->size(); ++(e->fIterator.first), --e->fIdx){ }
783  e->fIterator.second = (e->fIterator.first != c->size()) ? c->test(e->fIterator.first) : false;
784  return &(e->fIterator.second);
785  }
786  static void* construct(void*,size_t) {
787  // Nothing to construct.
788  return 0;
789  }
790  static void* collect(void *coll, void *array) {
791  PCont_t c = PCont_t(coll);
792  PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
793  for (size_t i=0; i != c->size(); ++i, ++m )
794  *m = c->test(i);
795  return 0;
796  }
797  static void destruct(void*,size_t) {
798  // Nothing to destruct.
799  }
800 
801  //static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
802  //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
803 
804  struct Iterators {
805  union PtrSize_t { size_t fIndex; void *fAddress; };
806  typedef std::pair<PtrSize_t,Bool_t> iterator;
807  // In the end iterator we store the bitset pointer
808  // and do not use the 'second' part of the pair.
809  // In the other iterator we store the index
810  // and the value.
811 
812  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
813  iterator *begin = new (*begin_arena) iterator;
814  begin->first.fIndex = 0;
815  begin->second = false;
816  iterator *end = new (*end_arena) iterator;
817  end->first.fAddress = coll;
818  end->second = false;
819  }
820  static void* copy(void *dest_arena, const void *source_ptr) {
821  const iterator *source = (const iterator *)(source_ptr);
822  new (dest_arena) iterator(*source);
823  return dest_arena;
824  }
825  static void* next(void *iter_loc, const void *end_loc) {
826  const iterator *end = (const iterator *)(end_loc);
827  PCont_t c = (PCont_t)end->first.fAddress;
828  iterator *iter = (iterator *)(iter_loc);
829  if (iter->first.fIndex != c->size()) {
830  iter->second = c->test(iter->first.fIndex);
831  ++(iter->first.fIndex);
832  }
833  return &(iter->second);
834  }
835  static void destruct1(void *iter_ptr) {
836  iterator *start = (iterator *)(iter_ptr);
837  start->~iterator();
838  }
839  static void destruct2(void *begin_ptr, void *end_ptr) {
840  iterator *start = (iterator *)(begin_ptr);
841  iterator *end = (iterator *)(end_ptr);
842  start->~iterator();
843  end->~iterator();
844  }
845  };
847  };
848 
849  template <typename Bitset_t>
850  struct TCollectionProxyInfo::Pushback<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > {
852  using typename InfoBase_t::Cont_t;
853  using typename InfoBase_t::Iter_t;
854  using typename InfoBase_t::Value_t;
855  using typename InfoBase_t::Env_t;
856  using typename InfoBase_t::PEnv_t;
857  using typename InfoBase_t::PCont_t;
858  using typename InfoBase_t::PValue_t;
859 
860  static void resize(void*,size_t) {
861  }
862  static void* feed(void *from, void *to, size_t size) {
863  PCont_t c = PCont_t(to);
864  PValue_t m = PValue_t(from);
865  for (size_t i=0; i<size; ++i, ++m)
866  c->set(i,*m);
867  return 0;
868  }
869  static int value_offset() {
870  return 0;
871  }
872  };
873 
874 } // namespace Detail
875 
876 // For (reasonable) backward compatibility:
877 using namespace Detail;
878 } // namespace ROOT
879 
880 #endif
static size_t GetContainerSize(const std::forward_list< T, ALLOCATOR > &c)
static void * copy(void *dest_arena, const void *source_ptr)
static void * copy(void *, const void *source_ptr)
static void * next(void *iter_loc, const void *end_loc)
auto * m
Definition: textangle.C:8
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
static void * feed(void *from, void *to, size_t size)
double T(double x)
Definition: ChebyshevPol.h:34
Small helper to encapsulate all necessary data accesses for containers like set, multiset etc...
#define R__ASSERT(e)
Definition: TError.h:96
static void destruct2(void *begin_ptr, void *end_ptr)
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
bool Bool_t
Definition: RtypesCore.h:59
STL namespace.
static void * next(void *iter_loc, const void *end_loc)
#define TYPENAME
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
Small helper to encapsulate basic data accesses for all STL continers.
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
Small helper to implement the function to create,access and destroy iterators.
TCollectionProxyInfo(const std::type_info &info, size_t iter_size, size_t value_diff, int value_offset, void *(*size_func)(void *), void(*resize_func)(void *, size_t), void *(*clear_func)(void *), void *(*first_func)(void *), void *(*next_func)(void *), void *(*construct_func)(void *, size_t), void(*destruct_func)(void *, size_t), void *(*feed_func)(void *, void *, size_t), void *(*collect_func)(void *, void *), void *(*create_env)(), void(*getIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)=0, void *(*copyIterator)(void *dest, const void *source)=0, void *(*next)(void *iter, const void *end)=0, void(*deleteSingleIterator)(void *iter)=0, void(*deleteTwoIterators)(void *begin, void *end)=0)
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
static void * construct(void *what, size_t size)
Small helper to encapsulate all necessary data accesses for containers like set, multiset etc...
static constexpr double second
static void * collect(void *coll, void *array)
Small helper to save proxy environment in the event of recursive calls.
Small helper to encapsulate all necessary data accesses for containers like vector, list, deque.
static void * feed(void *from, void *to, size_t size)
Iterators< Cont_t, fgLargeIterator > Iterators_t
static void destruct(void *what, size_t size)
unsigned int UInt_t
Definition: RtypesCore.h:42
Small helper to encapsulate all necessary data accesses for containers like forward_list.
Small helper to encapsulate whether to return the value pointed to by the iterator or its address...
const Bool_t kFALSE
Definition: RtypesCore.h:88
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
static TCollectionProxyInfo Get(const T &)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
Binding & operator=(OUT(*fun)(void))
static void * feed(void *from, void *to, size_t size)
typedef void((*Func_t)())
#define dest(otri, vertexptr)
Definition: triangle.c:1040
static void * feed(void *from, void *to, size_t size)
static TCollectionProxyInfo * Generate(const T &)
Generate proxy from template.
const Int_t n
Definition: legend1.C:16
static double Q[]
static void * copy(void *dest_arena, const void *source_ptr)