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