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