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