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 <typeinfo>
27#include <utility>
28
29#if defined(_WIN32)
30 #if _MSC_VER<1300
31 #define TYPENAME
32 #define R__VCXX6
33 #else
34 #define TYPENAME typename
35 #endif
36#else
37 #define TYPENAME typename
38#endif
39
41
42namespace ROOT {
43namespace VecOps {
44template <typename T>
45class RVec;
46}
47
48namespace Internal {
49template <typename T> class TStdBitsetHelper {
50 // This class is intentionally empty, this is scaffolding to allow the equivalent
51 // of 'template <int N> struct TCollectionProxyInfo::Type<std::bitset<N> >' which
52 // is not effective in C++ (as of gcc 4.3.3).
53};
54}
55
56namespace Detail {
57
59 // This class is a place holder for the information needed
60 // to create the proper Collection Proxy.
61 // This is similar to Reflex's CollFuncTable.
62
63 public:
64
65 // Same value as TVirtualCollectionProxy.
66 static const UInt_t fgIteratorArenaSize = 16; // greater than sizeof(void*) + sizeof(UInt_t)
67
68 /** @class ROOT::Detail::TCollectionProxyInfo::IteratorValue
69 *
70 * Small helper to encapsulate whether to return the value
71 * pointed to by the iterator or its address.
72 *
73 **/
74
75 template <typename Cont_t, typename value> struct IteratorValue {
76 static void* get(typename Cont_t::iterator &iter) {
77 return (void*)&(*iter);
78 }
79 };
80
81 template <typename Cont_t, typename value_ptr> struct IteratorValue<Cont_t, value_ptr*> {
82 static void* get(typename Cont_t::iterator &iter) {
83 return (void*)(*iter);
84 }
85 };
86
87 /** @class ROOT::Detail::TCollectionProxyInfo::Iterators
88 *
89 * Small helper to implement the function to create,access and destroy
90 * iterators.
91 *
92 **/
93
94 template <typename Cont_t, bool large = false>
95 struct Iterators {
96 typedef Cont_t *PCont_t;
97 typedef typename Cont_t::iterator iterator;
98
99 static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
101 new (*begin_arena) iterator(c->begin());
102 new (*end_arena) iterator(c->end());
103 }
104 static void* copy(void *dest_arena, const void *source_ptr) {
106 new (dest_arena) iterator(*source);
107 return dest_arena;
108 }
109 static void* next(void *iter_loc, const void *end_loc) {
110 iterator *end = (iterator *)(end_loc);
111 iterator *iter = (iterator *)(iter_loc);
112 if (*iter != *end) {
114 ++(*iter);
115 return result;
116 }
117 return nullptr;
118 }
119 static void destruct1(void *iter_ptr) {
120 iterator *start = (iterator *)(iter_ptr);
121 start->~iterator();
122 }
123 static void destruct2(void *begin_ptr, void *end_ptr) {
124 iterator *start = (iterator *)(begin_ptr);
125 iterator *end = (iterator *)(end_ptr);
126 start->~iterator();
127 end->~iterator();
128 }
129 };
130
131 // For Vector we take an extra short cut to avoid derefencing
132 // the iterator all the time and redefine the 'address' of the
133 // iterator as the iterator itself. This requires special handling
134 // in the looper (see TStreamerInfoAction) but is much faster.
135 template <typename T> struct Iterators<std::vector<T>, false> {
136 typedef std::vector<T> Cont_t;
137 typedef Cont_t *PCont_t;
138 typedef typename Cont_t::iterator iterator;
139
140 static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
142 if (c->empty()) {
143 *begin_arena = nullptr;
144 *end_arena = nullptr;
145 return;
146 }
147 *begin_arena = c->data();
148 *end_arena = c->data() + c->size(); // We can not dereference the end iterator at all.
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 nullptr;
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*) {
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) {
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 nullptr;
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:
224 EnvironBase() : fIdx(0), fSize(0), fObject(nullptr), fStart(nullptr), fTemp(nullptr), fUseTemp(kFALSE), fRefCount(1), fSpace(0)
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 nullptr;
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 = nullptr;
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 nullptr;
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 nullptr;
341 }
342 static void* collect(void *coll, void *array) {
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 nullptr;
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 nullptr;
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 nullptr;
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 nullptr;
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 nullptr;
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 nullptr;
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.
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
527 void (*fDeleteSingleIterator)(void *iter);
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) = nullptr,
548 void* (*copyIterator)(void *dest, const void *source) = nullptr,
549 void* (*next)(void *iter, const void *end) = nullptr,
550 void (*deleteSingleIterator)(void *iter) = nullptr,
551 void (*deleteTwoIterators)(void *begin, void *end) = nullptr
552 ) :
554 fValueOffset(value_offset),
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 nullptr;
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 nullptr;
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 nullptr;
665 }
666 static void* construct(void*,size_t) {
667 // Nothing to construct.
668 return nullptr;
669 }
670 static void* collect(void *coll, void *array) {
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 nullptr;
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 nullptr;
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 {
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 nullptr;
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 nullptr;
793 }
794 static void* collect(void *coll, void *array) {
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 nullptr;
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 return &(iter->second);
837 } else {
838 return nullptr;
839 }
840 }
841 static void destruct1(void *iter_ptr) {
842 iterator *start = (iterator *)(iter_ptr);
843 start->~iterator();
844 }
845 static void destruct2(void *begin_ptr, void *end_ptr) {
846 iterator *start = (iterator *)(begin_ptr);
847 iterator *end = (iterator *)(end_ptr);
848 start->~iterator();
849 end->~iterator();
850 }
851 };
853 };
854
855 template <typename Bitset_t>
856 struct TCollectionProxyInfo::Pushback<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > {
865
866 static void resize(void*,size_t) {
867 }
868 static void* feed(void *from, void *to, size_t size) {
869 PCont_t c = PCont_t(to);
870 PValue_t m = PValue_t(from);
871 for (size_t i=0; i<size; ++i, ++m)
872 c->set(i,*m);
873 return nullptr;
874 }
875 static int value_offset() {
876 return 0;
877 }
878 };
879
880} // namespace Detail
881
882// For (reasonable) backward compatibility:
883using namespace Detail;
884} // namespace ROOT
885
886#endif
#define c(i)
Definition RSha256.hxx:101
#define e(i)
Definition RSha256.hxx:103
Basic types used by ROOT and required by TInterpreter.
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
#define TYPENAME
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
void *(* fCopyIterator)(void *dest, const void *source)
void *(* fConstructFunc)(void *, size_t)
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)=nullptr, void *(*copyIterator)(void *dest, const void *source)=nullptr, void *(*next)(void *iter, const void *end)=nullptr, void(*deleteSingleIterator)(void *iter)=nullptr, void(*deleteTwoIterators)(void *begin, void *end)=nullptr)
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)
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1525
Defines a common interface to inspect/change the contents of an object that represents a collection.
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...
static const char * what
Definition stlLoader.cc:5
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)
TMarker m
Definition textangle.C:8