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