ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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;
233  size_t fSpace;
234  };
235  template <typename T> struct Environ : public EnvironBase {
237  typedef T Iter_t;
239  T& iter() { return fIterator; }
240  static void *Create() {
241  return new Environ();
242  }
243  };
244 #else
245  struct EnvironBase;
246  template <typename T> struct Environ;
247 #endif
248 
249  template <class T, class Q> struct PairHolder {
254  virtual ~PairHolder() {}
255  private:
256  PairHolder& operator=(const PairHolder&); // not implemented
257  };
258 
259  template <class T> struct Address {
260  virtual ~Address() {}
261  static void* address(T ref) {
262  return const_cast<void*>(reinterpret_cast<const void*>(&ref));
263  }
264  };
265 
266  struct SfinaeHelper {
267  // Use SFINAE to get the size of the container
268 
269  // In general we get the size of the container with the size method
270  template <class T>
271  static size_t GetContainerSize(const T& c) {return c.size();}
272 
273  // Since forward_list does not provide a size operator, we have to
274  // use an alternative. This has a cost of course.
275  template <class T, class ALLOCATOR>
276  static size_t GetContainerSize(const std::forward_list<T,ALLOCATOR>& c) {return std::distance(c.begin(),c.end());}
277  };
278 
279  /** @class TCollectionProxyInfo::Type TCollectionProxyInfo.h TCollectionProxyInfo.h
280  *
281  * Small helper to encapsulate basic data accesses for
282  * all STL continers.
283  *
284  * @author M.Frank
285  * @version 1.0
286  * @date 10/10/2004
287  */
288  template <class T> struct Type
289  : public Address<TYPENAME T::const_reference>
290  {
291  typedef T Cont_t;
292  typedef typename T::iterator Iter_t;
293  typedef typename T::value_type Value_t;
295  typedef Env_t *PEnv_t;
296  typedef Cont_t *PCont_t;
297  typedef Value_t *PValue_t;
298 
299  virtual ~Type() {}
300 
301  static inline PCont_t object(void* ptr) {
302  return PCont_t(PEnv_t(ptr)->fObject);
303  }
304  static void* size(void* env) {
305  PEnv_t e = PEnv_t(env);
307  return &e->fSize;
308  }
309  static void* clear(void* env) {
310  object(env)->clear();
311  return 0;
312  }
313  static void* first(void* env) {
314  PEnv_t e = PEnv_t(env);
315  PCont_t c = PCont_t(e->fObject);
316 #if 0
317  // Assume iterators do not need destruction
318  ::new(e->buff) Iter_t(c->begin());
319 #endif
320  e->fIterator = c->begin();
322  if ( 0 == e->fSize ) return e->fStart = 0;
323  TYPENAME T::const_reference ref = *(e->iter());
324  return e->fStart = Type<T>::address(ref);
325  }
326  static void* next(void* env) {
327  PEnv_t e = PEnv_t(env);
328  PCont_t c = PCont_t(e->fObject);
329  for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
330  // TODO: Need to find something for going backwards....
331  if ( e->iter() == c->end() ) return 0;
332  TYPENAME T::const_reference ref = *(e->iter());
333  return Type<T>::address(ref);
334  }
335  static void* construct(void *what, size_t size) {
336  PValue_t m = PValue_t(what);
337  for (size_t i=0; i<size; ++i, ++m)
338  ::new(m) Value_t();
339  return 0;
340  }
341  static void* collect(void *coll, void *array) {
342  PCont_t c = PCont_t(coll);
343  PValue_t m = PValue_t(array);
344  for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
345  ::new(m) Value_t(*i);
346  return 0;
347  }
348  static void destruct(void *what, size_t size) {
349  PValue_t m = PValue_t(what);
350  for (size_t i=0; i < size; ++i, ++m )
351  m->~Value_t();
352  }
353 
354  static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
356 
357  };
358 
359  /** @class TCollectionProxyInfo::Map TCollectionProxyInfo.h TCollectionProxyInfo.h
360  *
361  * Small helper to encapsulate all necessary data accesses for
362  * containers like vector, list, deque
363  *
364  * @author M.Frank
365  * @version 1.0
366  * @date 10/10/2004
367  */
368  template <class T> struct Pushback : public Type<T> {
369  typedef T Cont_t;
370  typedef typename T::iterator Iter_t;
371  typedef typename T::value_type Value_t;
373  typedef Env_t *PEnv_t;
374  typedef Cont_t *PCont_t;
375  typedef Value_t *PValue_t;
376  static void resize(void* obj, size_t n) {
377  PCont_t c = PCont_t(obj);
378  c->resize(n);
379  }
380  static void* feed(void *from, void *to, size_t size) {
381  PCont_t c = PCont_t(to);
382  PValue_t m = PValue_t(from);
383  for (size_t i=0; i<size; ++i, ++m)
384  c->push_back(*m);
385  return 0;
386  }
387  static int value_offset() {
388  return 0;
389  }
390  };
391 
392  /** @class TCollectionProxyInfo::Pushfront TCollectionProxyInfo.h TCollectionProxyInfo.h
393  *
394  * Small helper to encapsulate all necessary data accesses for
395  * containers like forward_list
396  *
397  * @author D.Piparo
398  * @version 1.0
399  * @date 26/02/2015
400  */
401  template <class T> struct Pushfront : public Type<T> {
402  typedef T Cont_t;
403  typedef typename T::iterator Iter_t;
404  typedef typename T::value_type Value_t;
406  typedef Env_t *PEnv_t;
407  typedef Cont_t *PCont_t;
408  typedef Value_t *PValue_t;
409  static void resize(void* obj, size_t n) {
410  PCont_t c = PCont_t(obj);
411  c->resize(n);
412  }
413  static void* feed(void *from, void *to, size_t size) {
414  PCont_t c = PCont_t(to);
415  if (size==0) return 0;
416  PValue_t m = &(PValue_t(from)[size-1]); // Take the last item
417  // Iterate backwards not to revert ordering
418  for (size_t i=0; i<size; ++i, --m){
419  c->push_front(*m);
420  }
421  return 0;
422  }
423  static int value_offset() {
424  return 0;
425  }
426  };
427 
428  /** @class TCollectionProxyInfo::Map TCollectionProxyInfo.h TCollectionProxyInfo.h
429  *
430  * Small helper to encapsulate all necessary data accesses for
431  * containers like set, multiset etc.
432  *
433  * @author M.Frank
434  * @version 1.0
435  * @date 10/10/2004
436  */
437  template <class T> struct Insert : public Type<T> {
438  typedef T Cont_t;
439  typedef typename T::iterator Iter_t;
440  typedef typename T::value_type Value_t;
442  typedef Env_t *PEnv_t;
443  typedef Cont_t *PCont_t;
444  typedef Value_t *PValue_t;
445  static void* feed(void *from, void *to, size_t size) {
446  PCont_t c = PCont_t(to);
447  PValue_t m = PValue_t(from);
448  for (size_t i=0; i<size; ++i, ++m)
449  c->insert(*m);
450  return 0;
451  }
452  static void resize(void* /* obj */, size_t ) {
453  ;
454  }
455  static int value_offset() {
456  return 0;
457  }
458  };
459 
460  /** @class TCollectionProxyInfo::Map TCollectionProxyInfo.h TCollectionProxyInfo.h
461  *
462  * Small helper to encapsulate all necessary data accesses for
463  * containers like set, multiset etc.
464  *
465  * @author M.Frank
466  * @version 1.0
467  * @date 10/10/2004
468  */
469  template <class T> struct MapInsert : public Type<T> {
470  typedef T Cont_t;
471  typedef typename T::iterator Iter_t;
472  typedef typename T::value_type Value_t;
474  typedef Env_t *PEnv_t;
475  typedef Cont_t *PCont_t;
476  typedef Value_t *PValue_t;
477  static void* feed(void *from, void *to, size_t size) {
478  PCont_t c = PCont_t(to);
479  PValue_t m = PValue_t(from);
480  for (size_t i=0; i<size; ++i, ++m)
481  c->insert(*m);
482  return 0;
483  }
484  static void resize(void* /* obj */, size_t ) {
485  ;
486  }
487  static int value_offset() {
488  return ((char*)&((PValue_t(0x1000))->second)) - ((char*)PValue_t(0x1000));
489  }
490  };
491 
492 
493  public:
494 #ifndef __CINT__
495  const type_info &fInfo;
496 #endif
497  size_t fIterSize;
498  size_t fValueDiff;
500  void* (*fSizeFunc)(void*);
502  void* (*fClearFunc)(void*);
503  void* (*fFirstFunc)(void*);
504  void* (*fNextFunc)(void*);
505  void* (*fConstructFunc)(void*,size_t);
507  void* (*fFeedFunc)(void*,void*,size_t);
508  void* (*fCollectFunc)(void*,void*);
509  void* (*fCreateEnv)();
510 
511  // Set of function of direct iteration of the collections.
512  void (*fCreateIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy);
513  // begin_arena and end_arena should contain the location of memory arena of size fgIteratorSize.
514  // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
515  // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
516 
517  void* (*fCopyIterator)(void *dest, const void *source);
518  // Copy the iterator source, into dest. dest should contain should contain the location of memory arena of size fgIteratorSize.
519  // If the collection iterator are of that size or less, the iterator will be constructed in place in this location (new with placement)
520  // Otherwise the iterator will be allocated via a regular new and its address returned by modifying the value of dest.
521 
522  void* (*fNext)(void *iter, const void *end);
523  // iter and end should be pointer to respectively an iterator to be incremented and the result of colleciton.end()
524  // 'Next' will increment the iterator 'iter' and return 0 if the iterator reached the end.
525  // If the end is not reached, 'Next' will return the address of the content unless the collection contains pointers in
526  // which case 'Next' will return the value of the pointer.
527 
529  void (*fDeleteTwoIterators)(void *begin, void *end);
530  // If the sizeof iterator is greater than fgIteratorArenaSize, call delete on the addresses,
531  // Otherwise just call the iterator's destructor.
532 
533  public:
534  TCollectionProxyInfo(const type_info& info,
535  size_t iter_size,
536  size_t value_diff,
537  int value_offset,
538  void* (*size_func)(void*),
539  void (*resize_func)(void*,size_t),
540  void* (*clear_func)(void*),
541  void* (*first_func)(void*),
542  void* (*next_func)(void*),
543  void* (*construct_func)(void*,size_t),
544  void (*destruct_func)(void*,size_t),
545  void* (*feed_func)(void*,void*,size_t),
546  void* (*collect_func)(void*,void*),
547  void* (*create_env)(),
548  void (*getIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy) = 0,
549  void* (*copyIterator)(void *dest, const void *source) = 0,
550  void* (*next)(void *iter, const void *end) = 0,
551  void (*deleteSingleIterator)(void *iter) = 0,
552  void (*deleteTwoIterators)(void *begin, void *end) = 0
553  ) :
554  fInfo(info), fIterSize(iter_size), fValueDiff(value_diff),
555  fValueOffset(value_offset),
556  fSizeFunc(size_func),fResizeFunc(resize_func),fClearFunc(clear_func),
557  fFirstFunc(first_func),fNextFunc(next_func),fConstructFunc(construct_func),
558  fDestructFunc(destruct_func),fFeedFunc(feed_func),fCollectFunc(collect_func),
559  fCreateEnv(create_env),
560  fCreateIterators(getIterators),fCopyIterator(copyIterator),fNext(next),
561  fDeleteSingleIterator(deleteSingleIterator),fDeleteTwoIterators(deleteTwoIterators)
562  {
563  }
564 
565  /// Generate proxy from template
566  template <class T> static TCollectionProxyInfo* Generate(const T&) {
567  // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
568  // template (used to described the behavior of the stl collection.
569  // Typical use looks like:
570  // ::ROOT::Detail::TCollectionProxyInfo::Generate(TCollectionProxyInfo::Pushback< std::vector<string> >()));
571 
574  return new TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
575  sizeof(TYPENAME T::Iter_t),
576  (((char*)&p->second)-((char*)&p->first)),
577  T::value_offset(),
578  T::size,
579  T::resize,
580  T::clear,
581  T::first,
582  T::next,
583  T::construct,
584  T::destruct,
585  T::feed,
586  T::collect,
587  T::Env_t::Create,
588  T::Iterators_t::create,
589  T::Iterators_t::copy,
591  T::Iterators_t::destruct1,
592  T::Iterators_t::destruct2);
593  }
594 
595  template <class T> static TCollectionProxyInfo Get(const T&) {
596 
597  // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
598  // template (used to described the behavior of the stl collection.
599  // Typical use looks like:
600  // ::ROOT::Detail::TCollectionProxyInfo::Get(TCollectionProxyInfo::Pushback< std::vector<string> >()));
601 
604  return TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
605  sizeof(TYPENAME T::Iter_t),
606  (((char*)&p->second)-((char*)&p->first)),
607  T::value_offset(),
608  T::size,
609  T::resize,
610  T::clear,
611  T::first,
612  T::next,
613  T::construct,
614  T::destruct,
615  T::feed,
616  T::collect,
617  T::Env_t::Create);
618  }
619 
620  };
621 
622  template <> struct TCollectionProxyInfo::Type<std::vector<Bool_t> >
623  : public TCollectionProxyInfo::Address<std::vector<Bool_t>::const_reference>
624  {
625  typedef std::vector<Bool_t> Cont_t;
626  typedef std::vector<Bool_t>::iterator Iter_t;
627  typedef std::vector<Bool_t>::value_type Value_t;
629  typedef Env_t *PEnv_t;
630  typedef Cont_t *PCont_t;
631  typedef Value_t *PValue_t;
632 
633  virtual ~Type() {}
634 
635  static inline PCont_t object(void* ptr) {
636  return PCont_t(PEnv_t(ptr)->fObject);
637  }
638  static void* size(void* env) {
639  PEnv_t e = PEnv_t(env);
640  e->fSize = PCont_t(e->fObject)->size();
641  return &e->fSize;
642  }
643  static void* clear(void* env) {
644  object(env)->clear();
645  return 0;
646  }
647  static void* first(void* env) {
648  PEnv_t e = PEnv_t(env);
649  PCont_t c = PCont_t(e->fObject);
650 #if 0
651  // Assume iterators do not need destruction
652  ::new(e->buff) Iter_t(c->begin());
653 #endif
654  e->fIterator = c->begin();
655  e->fSize = c->size();
656  return 0;
657  }
658  static void* next(void* env) {
659  PEnv_t e = PEnv_t(env);
660  PCont_t c = PCont_t(e->fObject);
661  for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
662  // TODO: Need to find something for going backwards....
663  return 0;
664  }
665  static void* construct(void*,size_t) {
666  // Nothing to construct.
667  return 0;
668  }
669  static void* collect(void *coll, void *array) {
670  PCont_t c = PCont_t(coll);
671  PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
672  for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
673  ::new(m) Value_t(*i);
674  return 0;
675  }
676  static void destruct(void*,size_t) {
677  // Nothing to destruct.
678  }
679 
680  //static const bool fgLargeIterator = sizeof(Cont_t::iterator) > fgIteratorArenaSize;
681  //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
682 
683  struct Iterators {
684  typedef Cont_t *PCont_t;
685  typedef Cont_t::iterator iterator;
686 
687  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
688  PCont_t c = PCont_t(coll);
689  new (*begin_arena) iterator(c->begin());
690  new (*end_arena) iterator(c->end());
691  }
692  static void* copy(void *dest_arena, const void *source_ptr) {
693  const iterator *source = (const iterator *)(source_ptr);
694  new (dest_arena) iterator(*source);
695  return dest_arena;
696  }
697  static void* next(void *iter_loc, const void *end_loc) {
698  const iterator *end = (const iterator *)(end_loc);
699  iterator *iter = (iterator *)(iter_loc);
700  if (*iter != *end) {
701  ++(*iter);
702  //if (*iter != *end) {
703  // return IteratorValue<Cont_t, Cont_t::value_type>::get(*iter);
704  //}
705  }
706  return 0;
707  }
708  static void destruct1(void *iter_ptr) {
709  iterator *start = (iterator *)(iter_ptr);
710  start->~iterator();
711  }
712  static void destruct2(void *begin_ptr, void *end_ptr) {
713  iterator *start = (iterator *)(begin_ptr);
714  iterator *end = (iterator *)(end_ptr);
715  start->~iterator();
716  end->~iterator();
717  }
718  };
720 
721  };
722 
723  template <> struct TCollectionProxyInfo::Pushback<std::vector<bool> > : public TCollectionProxyInfo::Type<std::vector<Bool_t> > {
724  typedef std::vector<Bool_t> Cont_t;
725  typedef Cont_t::iterator Iter_t;
726  typedef Cont_t::value_type Value_t;
728  typedef Env_t *PEnv_t;
729  typedef Cont_t *PCont_t;
730  typedef Value_t *PValue_t;
731 
732  static void resize(void* obj,size_t n) {
733  PCont_t c = PCont_t(obj);
734  c->resize(n);
735  }
736  static void* feed(void* from, void *to, size_t size) {
737  PCont_t c = PCont_t(to);
738  PValue_t m = PValue_t(from);
739  for (size_t i=0; i<size; ++i, ++m)
740  c->push_back(*m);
741  return 0;
742  }
743  static int value_offset() {
744  return 0;
745  }
746  };
747 
748 #ifndef __CINT__
749  // Need specialization for boolean references due to stupid STL std::vector<bool>
750  template<> inline void* TCollectionProxyInfo::Address<std::vector<Bool_t>::const_reference>::address(std::vector<Bool_t>::const_reference ) {
751  R__ASSERT(0);
752  return 0;
753  }
754 #endif
755 
756 #ifndef __CINT__
757  template <typename Bitset_t> struct TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Address<const Bool_t &>
758  {
759  typedef Bitset_t Cont_t;
760  typedef std::pair<size_t,Bool_t> Iter_t;
761  typedef Bool_t Value_t;
763  typedef Env_t *PEnv_t;
764  typedef Cont_t *PCont_t;
765  typedef Value_t *PValue_t;
766 
767  virtual ~Type() {}
768 
769  static inline PCont_t object(void* ptr) {
770  return PCont_t(PEnv_t(ptr)->fObject);
771  }
772  static void* size(void* env) {
773  PEnv_t e = PEnv_t(env);
774  e->fSize = PCont_t(e->fObject)->size();
775  return &e->fSize;
776  }
777  static void* clear(void* env) {
778  object(env)->reset();
779  return 0;
780  }
781  static void* first(void* env) {
782  PEnv_t e = PEnv_t(env);
783  PCont_t c = PCont_t(e->fObject);
784  e->fIterator.first = 0;
785  e->fIterator.second = c->size() > 0 ? c->test(e->fIterator.first) : false ; // Iterator actually hold the value.
786  e->fSize = c->size();
787  return 0;
788  }
789  static void* next(void* env) {
790  PEnv_t e = PEnv_t(env);
791  PCont_t c = PCont_t(e->fObject);
792  for (; e->fIdx > 0 && e->fIterator.first != c->size(); ++(e->fIterator.first), --e->fIdx){ }
793  e->fIterator.second = (e->fIterator.first != c->size()) ? c->test(e->fIterator.first) : false;
794  return 0;
795  }
796  static void* construct(void*,size_t) {
797  // Nothing to construct.
798  return 0;
799  }
800  static void* collect(void *coll, void *array) {
801  PCont_t c = PCont_t(coll);
802  PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
803  for (size_t i=0; i != c->size(); ++i, ++m )
804  *m = c->test(i);
805  return 0;
806  }
807  static void destruct(void*,size_t) {
808  // Nothing to destruct.
809  }
810 
811  //static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
812  //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
813 
814  struct Iterators {
815  typedef Cont_t *PCont_t;
816  union PtrSize_t { size_t fIndex; void *fAddress; };
817  typedef std::pair<PtrSize_t,Bool_t> iterator;
818  // In the end iterator we store the bitset pointer
819  // and do not use the 'second' part of the pair.
820  // In the other iterator we store the index
821  // and the value.
822 
823  static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
824  iterator *begin = new (*begin_arena) iterator;
825  begin->first.fIndex = 0;
826  begin->second = false;
827  iterator *end = new (*end_arena) iterator;
828  end->first.fAddress = coll;
829  end->second = false;
830  }
831  static void* copy(void *dest_arena, const void *source_ptr) {
832  const iterator *source = (const iterator *)(source_ptr);
833  new (dest_arena) iterator(*source);
834  return dest_arena;
835  }
836  static void* next(void *iter_loc, const void *end_loc) {
837  const iterator *end = (const iterator *)(end_loc);
838  PCont_t c = (PCont_t)end->first.fAddress;
839  iterator *iter = (iterator *)(iter_loc);
840  if (iter->first.fIndex != c->size()) {
841  iter->second = c->test(iter->first.fIndex);
842  ++(iter->first.fIndex);
843  }
844  return &(iter->second);
845  }
846  static void destruct1(void *iter_ptr) {
847  iterator *start = (iterator *)(iter_ptr);
848  start->~iterator();
849  }
850  static void destruct2(void *begin_ptr, void *end_ptr) {
851  iterator *start = (iterator *)(begin_ptr);
852  iterator *end = (iterator *)(end_ptr);
853  start->~iterator();
854  end->~iterator();
855  }
856  };
858  };
859 
860  template <typename Bitset_t>
861  struct TCollectionProxyInfo::Pushback<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > {
862  typedef Bitset_t Cont_t;
863  typedef bool Iter_t;
864  typedef bool Value_t;
866  typedef Env_t *PEnv_t;
867  typedef Cont_t *PCont_t;
868  typedef Value_t *PValue_t;
869 
870  static void resize(void*,size_t) {
871  }
872  static void* feed(void *from, void *to, size_t size) {
873  PCont_t c = PCont_t(to);
874  PValue_t m = PValue_t(from);
875  for (size_t i=0; i<size; ++i, ++m)
876  c->set(i,*m);
877  return 0;
878  }
879  static int value_offset() {
880  return 0;
881  }
882  };
883 #endif
884 
885 } // namespace Detail
886 
887 // For (reasonable) backward compatibility:
888 using namespace Detail;
889 } // namespace ROOT
890 
891 #endif
static size_t GetContainerSize(const std::forward_list< T, ALLOCATOR > &c)
static void * copy(void *dest_arena, const void *source_ptr)
void *(* fNext)(void *iter, const void *end)
void(* fDeleteTwoIterators)(void *begin, void *end)
static void * copy(void *, const void *source_ptr)
static void * next(void *iter_loc, const void *end_loc)
void *(* fCollectFunc)(void *, void *)
static void * feed(void *from, void *to, size_t size)
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
return c
void *(* fCopyIterator)(void *dest, const void *source)
Double_t distance(const TPoint2 &p1, const TPoint2 &p2)
Definition: CsgOps.cxx:467
void *(* fFeedFunc)(void *, void *, size_t)
#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 *)
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
static void * next(void *iter_loc, const void *end_loc)
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Definition: TIterator.cxx:21
size_t
Definition: TBuffer.cxx:28
#define TYPENAME
static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy *)
TTree * T
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
void *(* fConstructFunc)(void *, size_t)
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(* fCreateIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
bool first
Definition: line3Dfit.C:48
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)())
#define dest(otri, vertexptr)
Definition: triangle.c:1040
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
static double Q[]
static void * copy(void *dest_arena, const void *source_ptr)