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