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