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 "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 0;
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 = 0;
143 *end_arena = 0;
144 return;
145 }
146 *begin_arena = &(*c->begin());
147#ifdef R__VISUAL_CPLUSPLUS
148 *end_arena = &(*(c->end()-1)) + 1; // On windows we can not dererence the end iterator at all.
149#else
150 // coverity[past_the_end] Safe on other platforms
151 *end_arena = &(*c->end());
152#endif
153 }
154 static void* copy(void *dest, const void *source) {
155 *(void**)dest = *(void**)(const_cast<void*>(source));
156 return dest;
157 }
158 static void* next(void * /* iter_loc */, const void * /* end_loc */) {
159 // Should not be used.
160 // In the case of vector, so that the I/O can perform better,
161 // the begin_arena and the end_arena are *not* set to the
162 // address of any iterator rather they are set to the value of
163 // the beginning (and end) address of the vector's data.
164 // Hence this routine (which takes the value of fBegin) can
165 // *not* update where its points to (which in the case of vector
166 // would require update the value of fBegin).
167 R__ASSERT(0 && "Intentionally not implemented, do not use.");
168 return 0;
169 }
170 static void destruct1(void * /* iter_ptr */) {
171 // Nothing to do
172 }
173 static void destruct2(void * /* begin_ptr */, void * /* end_ptr */) {
174 // Nothing to do
175 }
176 };
177
178 template <typename Cont_t> struct Iterators<Cont_t, /* large= */ true > {
179 typedef Cont_t *PCont_t;
180 typedef typename Cont_t::iterator iterator;
181
182 static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
183 PCont_t c = PCont_t(coll);
184 *begin_arena = new iterator(c->begin());
185 *end_arena = new iterator(c->end());
186 }
187 static void* copy(void * /*dest_arena*/, const void *source_ptr) {
188 iterator *source = (iterator *)(source_ptr);
189 void *iter = new iterator(*source);
190 return iter;
191 }
192 static void* next(void *iter_loc, const void *end_loc) {
193 iterator *end = (iterator *)(end_loc);
194 iterator *iter = (iterator *)(iter_loc);
195 if (*iter != *end) {
197 ++(*iter);
198 return result;
199 }
200 return 0;
201 }
202 static void destruct1(void *begin_ptr) {
203 iterator *start = (iterator *)(begin_ptr);
204 delete start;
205 }
206 static void destruct2(void *begin_ptr, void *end_ptr) {
207 iterator *start = (iterator *)(begin_ptr);
208 iterator *end = (iterator *)(end_ptr);
209 delete start;
210 delete end;
211 }
212 };
213
214 /** @class ROOT::Detail::TCollectionProxyInfo::Environ
215 *
216 * Small helper to save proxy environment in the event of
217 * recursive calls.
218 *
219 * @author M.Frank
220 * @version 1.0
221 * @date 10/10/2004
222 */
223 struct EnvironBase {
224 private:
225 EnvironBase(const EnvironBase&); // Intentionally not implement, copy is not supported
226 EnvironBase &operator=(const EnvironBase&); // Intentionally not implement, copy is not supported
227 public:
229 {
230 }
231 virtual ~EnvironBase() {}
232 size_t fIdx;
233 size_t fSize;
234 void* fObject;
235 void* fStart;
236 void* fTemp;
237 union {
240 };
242 size_t fSpace;
243 };
244 template <typename T> struct Environ : public EnvironBase {
246 typedef T Iter_t;
248 T& iter() { return fIterator; }
249 static void *Create() {
250 return new Environ();
251 }
252 };
253
254 template <class T, class Q> struct PairHolder {
259 virtual ~PairHolder() {}
260 private:
261 PairHolder& operator=(const PairHolder&) = delete;
262 };
263
264 template <class T> struct Address {
265 virtual ~Address() {}
266 static void* address(T ref) {
267 return const_cast<void*>(reinterpret_cast<const void*>(&ref));
268 }
269 };
270
272 // Use SFINAE to get the size of the container
273
274 // In general we get the size of the container with the size method
275 template <class T>
276 static size_t GetContainerSize(const T& c) {return c.size();}
277
278 // Since forward_list does not provide a size operator, we have to
279 // use an alternative. This has a cost of course.
280 template <class T, class ALLOCATOR>
281 static size_t GetContainerSize(const std::forward_list<T,ALLOCATOR>& c) {return std::distance(c.begin(),c.end());}
282 };
283
284 /** @class ROOT::Detail::TCollectionProxyInfo::Type
285 *
286 * Small helper to encapsulate basic data accesses for
287 * all STL continers.
288 *
289 * @author M.Frank
290 * @version 1.0
291 * @date 10/10/2004
292 */
293 template <class T> struct Type
294 : public Address<TYPENAME T::const_reference>
295 {
296 typedef T Cont_t;
297 typedef typename T::iterator Iter_t;
298 typedef typename T::value_type Value_t;
300 typedef Env_t *PEnv_t;
301 typedef Cont_t *PCont_t;
303
304 virtual ~Type() {}
305
306 static inline PCont_t object(void* ptr) {
307 return PCont_t(PEnv_t(ptr)->fObject);
308 }
309 static void* size(void* env) {
310 PEnv_t e = PEnv_t(env);
311 e->fSize = SfinaeHelper::GetContainerSize(*PCont_t(e->fObject));
312 return &e->fSize;
313 }
314 static void* clear(void* env) {
315 object(env)->clear();
316 return 0;
317 }
318 static void* first(void* env) {
319 PEnv_t e = PEnv_t(env);
320 PCont_t c = PCont_t(e->fObject);
321#if 0
322 // Assume iterators do not need destruction
323 ::new(e->buff) Iter_t(c->begin());
324#endif
325 e->fIterator = c->begin();
327 if ( 0 == e->fSize ) return e->fStart = 0;
328 TYPENAME T::const_reference ref = *(e->iter());
329 return e->fStart = Type<T>::address(ref);
330 }
331 static void* next(void* env) {
332 PEnv_t e = PEnv_t(env);
333 PCont_t c = PCont_t(e->fObject);
334 for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
335 // TODO: Need to find something for going backwards....
336 if ( e->iter() == c->end() ) return 0;
337 TYPENAME T::const_reference ref = *(e->iter());
338 return Type<T>::address(ref);
339 }
340 static void* construct(void *what, size_t size) {
342 for (size_t i=0; i<size; ++i, ++m)
343 ::new(m) Value_t();
344 return 0;
345 }
346 static void* collect(void *coll, void *array) {
347 PCont_t c = PCont_t(coll);
348 PValue_t m = PValue_t(array);
349 for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
350 ::new(m) Value_t(*i);
351 return 0;
352 }
353 static void destruct(void *what, size_t size) {
355 for (size_t i=0; i < size; ++i, ++m )
356 m->~Value_t();
357 }
358
359 static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
361
362 };
363
364 /** @class ROOT::Detail::TCollectionProxyInfo::Pushback
365 *
366 * Small helper to encapsulate all necessary data accesses for
367 * containers like vector, list, deque
368 *
369 * @author M.Frank
370 * @version 1.0
371 * @date 10/10/2004
372 */
373 template <class T> struct Pushback : public Type<T> {
374 typedef T Cont_t;
375 typedef typename T::iterator Iter_t;
376 typedef typename T::value_type Value_t;
378 typedef Env_t *PEnv_t;
379 typedef Cont_t *PCont_t;
381 static void resize(void* obj, size_t n) {
382 PCont_t c = PCont_t(obj);
383 c->resize(n);
384 }
385 static void* feed(void *from, void *to, size_t size) {
386 PCont_t c = PCont_t(to);
387 PValue_t m = PValue_t(from);
388 for (size_t i=0; i<size; ++i, ++m)
389 c->push_back(*m);
390 return 0;
391 }
392 static int value_offset() {
393 return 0;
394 }
395 };
396
397 /** @class ROOT::Detail::TCollectionProxyInfo::Pushfront
398 *
399 * Small helper to encapsulate all necessary data accesses for
400 * containers like forward_list
401 *
402 * @author D.Piparo
403 * @version 1.0
404 * @date 26/02/2015
405 */
406 template <class T> struct Pushfront : public Type<T> {
407 typedef T Cont_t;
408 typedef typename T::iterator Iter_t;
409 typedef typename T::value_type Value_t;
411 typedef Env_t *PEnv_t;
412 typedef Cont_t *PCont_t;
414 static void resize(void* obj, size_t n) {
415 PCont_t c = PCont_t(obj);
416 c->resize(n);
417 }
418 static void* feed(void *from, void *to, size_t size) {
419 PCont_t c = PCont_t(to);
420 if (size==0) return 0;
421 PValue_t m = &(PValue_t(from)[size-1]); // Take the last item
422 // Iterate backwards not to revert ordering
423 for (size_t i=0; i<size; ++i, --m){
424 c->push_front(*m);
425 }
426 return 0;
427 }
428 static int value_offset() {
429 return 0;
430 }
431 };
432
433 /** @class ROOT::Detail::TCollectionProxyInfo::Insert
434 *
435 * Small helper to encapsulate all necessary data accesses for
436 * containers like set, multiset etc.
437 *
438 * @author M.Frank
439 * @version 1.0
440 * @date 10/10/2004
441 */
442 template <class T> struct Insert : public Type<T> {
443 typedef T Cont_t;
444 typedef typename T::iterator Iter_t;
445 typedef typename T::value_type Value_t;
447 typedef Env_t *PEnv_t;
448 typedef Cont_t *PCont_t;
450 static void* feed(void *from, void *to, size_t size) {
451 PCont_t c = PCont_t(to);
452 PValue_t m = PValue_t(from);
453 for (size_t i=0; i<size; ++i, ++m)
454 c->insert(*m);
455 return 0;
456 }
457 static void resize(void* /* obj */, size_t ) {
458 ;
459 }
460 static int value_offset() {
461 return 0;
462 }
463 };
464
465 /** @class ROOT::Detail::TCollectionProxyInfo::MapInsert
466 *
467 * Small helper to encapsulate all necessary data accesses for
468 * containers like set, multiset etc.
469 *
470 * @author M.Frank
471 * @version 1.0
472 * @date 10/10/2004
473 */
474 template <class T> struct MapInsert : public Type<T> {
475 typedef T Cont_t;
476 typedef typename T::iterator Iter_t;
477 typedef typename T::value_type Value_t;
479 typedef Env_t *PEnv_t;
480 typedef Cont_t *PCont_t;
482 static void* feed(void *from, void *to, size_t size) {
483 PCont_t c = PCont_t(to);
484 PValue_t m = PValue_t(from);
485 for (size_t i=0; i<size; ++i, ++m)
486 c->insert(*m);
487 return 0;
488 }
489 static void resize(void* /* obj */, size_t ) {
490 ;
491 }
492 static int value_offset() {
493 return ((char*)&((PValue_t(0x1000))->second)) - ((char*)PValue_t(0x1000));
494 }
495 };
496
497
498 public:
499 const std::type_info &fInfo;
500 size_t fIterSize;
503 void* (*fSizeFunc)(void*);
504 void (*fResizeFunc)(void*,size_t);
505 void* (*fClearFunc)(void*);
506 void* (*fFirstFunc)(void*);
507 void* (*fNextFunc)(void*);
508 void* (*fConstructFunc)(void*,size_t);
509 void (*fDestructFunc)(void*,size_t);
510 void* (*fFeedFunc)(void*,void*,size_t);
511 void* (*fCollectFunc)(void*,void*);
512 void* (*fCreateEnv)();
513
514 // Set of function of direct iteration of the collections.
515 void (*fCreateIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy);
516 // begin_arena and end_arena should contain the location of memory arena of size fgIteratorSize.
517 // If the collection iterator are of that size or less, the iterators will be constructed in place in those location (new with placement)
518 // Otherwise the iterators will be allocated via a regular new and their address returned by modifying the value of begin_arena and end_arena.
519
520 void* (*fCopyIterator)(void *dest, const void *source);
521 // Copy the iterator source, into dest. dest should contain should contain the location of memory arena of size fgIteratorSize.
522 // If the collection iterator are of that size or less, the iterator will be constructed in place in this location (new with placement)
523 // Otherwise the iterator will be allocated via a regular new and its address returned by modifying the value of dest.
524
525 void* (*fNext)(void *iter, const void *end);
526 // iter and end should be pointer to respectively an iterator to be incremented and the result of colleciton.end()
527 // 'Next' will increment the iterator 'iter' and return 0 if the iterator reached the end.
528 // If the end is not reached, 'Next' will return the address of the content unless the collection contains pointers in
529 // which case 'Next' will return the value of the pointer.
530
532 void (*fDeleteTwoIterators)(void *begin, void *end);
533 // If the sizeof iterator is greater than fgIteratorArenaSize, call delete on the addresses,
534 // Otherwise just call the iterator's destructor.
535
536 public:
537 TCollectionProxyInfo(const std::type_info& info,
538 size_t iter_size,
539 size_t value_diff,
540 int value_offset,
541 void* (*size_func)(void*),
542 void (*resize_func)(void*,size_t),
543 void* (*clear_func)(void*),
544 void* (*first_func)(void*),
545 void* (*next_func)(void*),
546 void* (*construct_func)(void*,size_t),
547 void (*destruct_func)(void*,size_t),
548 void* (*feed_func)(void*,void*,size_t),
549 void* (*collect_func)(void*,void*),
550 void* (*create_env)(),
551 void (*getIterators)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy) = 0,
552 void* (*copyIterator)(void *dest, const void *source) = 0,
553 void* (*next)(void *iter, const void *end) = 0,
554 void (*deleteSingleIterator)(void *iter) = 0,
555 void (*deleteTwoIterators)(void *begin, void *end) = 0
556 ) :
557 fInfo(info), fIterSize(iter_size), fValueDiff(value_diff),
558 fValueOffset(value_offset),
559 fSizeFunc(size_func),fResizeFunc(resize_func),fClearFunc(clear_func),
560 fFirstFunc(first_func),fNextFunc(next_func),fConstructFunc(construct_func),
561 fDestructFunc(destruct_func),fFeedFunc(feed_func),fCollectFunc(collect_func),
562 fCreateEnv(create_env),
563 fCreateIterators(getIterators),fCopyIterator(copyIterator),fNext(next),
564 fDeleteSingleIterator(deleteSingleIterator),fDeleteTwoIterators(deleteTwoIterators)
565 {
566 }
567
568 /// Generate proxy from template
569 template <class T> static TCollectionProxyInfo* Generate(const T&) {
570 // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
571 // template (used to described the behavior of the stl collection.
572 // Typical use looks like:
573 // ::ROOT::Detail::TCollectionProxyInfo::Generate(TCollectionProxyInfo::Pushback< std::vector<string> >()));
574
577 return new TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
578 sizeof(TYPENAME T::Iter_t),
579 (((char*)&p->second)-((char*)&p->first)),
580 T::value_offset(),
581 T::size,
582 T::resize,
583 T::clear,
584 T::first,
585 T::next,
586 T::construct,
587 T::destruct,
588 T::feed,
589 T::collect,
590 T::Env_t::Create,
591 T::Iterators_t::create,
592 T::Iterators_t::copy,
593 T::Iterators_t::next,
594 T::Iterators_t::destruct1,
595 T::Iterators_t::destruct2);
596 }
597
598 template <class T> static TCollectionProxyInfo Get(const T&) {
599
600 // Generate a TCollectionProxyInfo given a TCollectionProxyInfo::Type
601 // template (used to described the behavior of the stl collection.
602 // Typical use looks like:
603 // ::ROOT::Detail::TCollectionProxyInfo::Get(TCollectionProxyInfo::Pushback< std::vector<string> >()));
604
607 return TCollectionProxyInfo(typeid(TYPENAME T::Cont_t),
608 sizeof(TYPENAME T::Iter_t),
609 (((char*)&p->second)-((char*)&p->first)),
610 T::value_offset(),
611 T::size,
612 T::resize,
613 T::clear,
614 T::first,
615 T::next,
616 T::construct,
617 T::destruct,
618 T::feed,
619 T::collect,
620 T::Env_t::Create);
621 }
622
623 };
624
625 // This specialization is chosen if T is a vector<bool, A>, irrespective of the nature
626 // of the allocator A represents.
627 template <class A> struct TCollectionProxyInfo::Type<std::vector<Bool_t, A>>
628 : public TCollectionProxyInfo::Address<typename std::vector<Bool_t, A>::const_reference>
629 {
630 typedef std::vector<Bool_t, A> Cont_t;
631 typedef typename Cont_t::iterator Iter_t;
632 typedef typename Cont_t::value_type Value_t;
633 typedef Environ<Iter_t> Env_t;
634 typedef Env_t *PEnv_t;
635 typedef Cont_t *PCont_t;
636 typedef Value_t *PValue_t;
637
638 virtual ~Type() {}
639
640 static inline PCont_t object(void* ptr) {
641 return PCont_t(PEnv_t(ptr)->fObject);
642 }
643 static void* size(void* env) {
644 PEnv_t e = PEnv_t(env);
645 e->fSize = PCont_t(e->fObject)->size();
646 return &e->fSize;
647 }
648 static void* clear(void* env) {
649 object(env)->clear();
650 return 0;
651 }
652 static void* first(void* env) {
653 PEnv_t e = PEnv_t(env);
654 PCont_t c = PCont_t(e->fObject);
655#if 0
656 // Assume iterators do not need destruction
657 ::new(e->buff) Iter_t(c->begin());
658#endif
659 e->fIterator = c->begin();
660 e->fSize = c->size();
661 return 0;
662 }
663 static void* next(void* env) {
664 PEnv_t e = PEnv_t(env);
665 PCont_t c = PCont_t(e->fObject);
666 for (; e->fIdx > 0 && e->iter() != c->end(); ++(e->iter()), --e->fIdx){ }
667 // TODO: Need to find something for going backwards....
668 return 0;
669 }
670 static void* construct(void*,size_t) {
671 // Nothing to construct.
672 return 0;
673 }
674 static void* collect(void *coll, void *array) {
675 PCont_t c = PCont_t(coll);
676 PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
677 for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
678 ::new(m) Value_t(*i);
679 return 0;
680 }
681 static void destruct(void*,size_t) {
682 // Nothing to destruct.
683 }
684
685 //static const bool fgLargeIterator = sizeof(Cont_t::iterator) > fgIteratorArenaSize;
686 //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
687
688 struct Iterators {
689 typedef typename Cont_t::iterator iterator;
690
691 static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
692 PCont_t c = PCont_t(coll);
693 new (*begin_arena) iterator(c->begin());
694 new (*end_arena) iterator(c->end());
695 }
696 static void* copy(void *dest_arena, const void *source_ptr) {
697 const iterator *source = (const iterator *)(source_ptr);
698 new (dest_arena) iterator(*source);
699 return dest_arena;
700 }
701 static void* next(void *, const void *) {
702 R__ASSERT(false && "Intentionally not implemented, should use VectorLooper or similar for vector<bool>.");
703 return {};
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) {
749 R__ASSERT(false && "Intentionally not implemented, should use VectorLooper or other functions specialized for "
750 "vector<bool> instead");
751 return {};
752 }
753 };
754
755 // TODO this can/should go away when we move to new RVec
756 template <>
758
759 template <typename Bitset_t> struct TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Address<const Bool_t &>
760 {
761 typedef Bitset_t Cont_t;
762 typedef std::pair<size_t,Bool_t> Iter_t;
765 typedef Env_t *PEnv_t;
766 typedef Cont_t *PCont_t;
768
769 virtual ~Type() {}
770
771 static inline PCont_t object(void* ptr) {
772 return PCont_t(PEnv_t(ptr)->fObject);
773 }
774 static void* size(void* env) {
775 PEnv_t e = PEnv_t(env);
776 e->fSize = PCont_t(e->fObject)->size();
777 return &e->fSize;
778 }
779 static void* clear(void* env) {
780 object(env)->reset();
781 return 0;
782 }
783 static void* first(void* env) {
784 PEnv_t e = PEnv_t(env);
785 PCont_t c = PCont_t(e->fObject);
786 e->fIterator.first = 0;
787 e->fIterator.second = c->size() > 0 ? c->test(e->fIterator.first) : false ; // Iterator actually hold the value.
788 e->fSize = c->size();
789 return &(e->fIterator.second);
790 }
791 static void* next(void* env) {
792 PEnv_t e = PEnv_t(env);
793 PCont_t c = PCont_t(e->fObject);
794 for (; e->fIdx > 0 && e->fIterator.first != c->size(); ++(e->fIterator.first), --e->fIdx){ }
795 e->fIterator.second = (e->fIterator.first != c->size()) ? c->test(e->fIterator.first) : false;
796 return &(e->fIterator.second);
797 }
798 static void* construct(void*,size_t) {
799 // Nothing to construct.
800 return 0;
801 }
802 static void* collect(void *coll, void *array) {
803 PCont_t c = PCont_t(coll);
804 PValue_t m = PValue_t(array); // 'start' is a buffer outside the container.
805 for (size_t i=0; i != c->size(); ++i, ++m )
806 *m = c->test(i);
807 return 0;
808 }
809 static void destruct(void*,size_t) {
810 // Nothing to destruct.
811 }
812
813 //static const bool fgLargeIterator = sizeof(typename Cont_t::iterator) > fgIteratorArenaSize;
814 //typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
815
816 struct Iterators {
817 union PtrSize_t { size_t fIndex; void *fAddress; };
818 typedef std::pair<PtrSize_t,Bool_t> iterator;
819 // In the end iterator we store the bitset pointer
820 // and do not use the 'second' part of the pair.
821 // In the other iterator we store the index
822 // and the value.
823
824 static void create(void *coll, void **begin_arena, void **end_arena, TVirtualCollectionProxy*) {
825 iterator *begin = new (*begin_arena) iterator;
826 begin->first.fIndex = 0;
827 begin->second = false;
828 iterator *end = new (*end_arena) iterator;
829 end->first.fAddress = coll;
830 end->second = false;
831 }
832 static void* copy(void *dest_arena, const void *source_ptr) {
833 const iterator *source = (const iterator *)(source_ptr);
834 new (dest_arena) iterator(*source);
835 return dest_arena;
836 }
837 static void* next(void *iter_loc, const void *end_loc) {
838 const iterator *end = (const iterator *)(end_loc);
839 PCont_t c = (PCont_t)end->first.fAddress;
840 iterator *iter = (iterator *)(iter_loc);
841 if (iter->first.fIndex != c->size()) {
842 iter->second = c->test(iter->first.fIndex);
843 ++(iter->first.fIndex);
844 }
845 return &(iter->second);
846 }
847 static void destruct1(void *iter_ptr) {
848 iterator *start = (iterator *)(iter_ptr);
849 start->~iterator();
850 }
851 static void destruct2(void *begin_ptr, void *end_ptr) {
852 iterator *start = (iterator *)(begin_ptr);
853 iterator *end = (iterator *)(end_ptr);
854 start->~iterator();
855 end->~iterator();
856 }
857 };
859 };
860
861 template <typename Bitset_t>
862 struct TCollectionProxyInfo::Pushback<Internal::TStdBitsetHelper<Bitset_t> > : public TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > {
864 using typename InfoBase_t::Cont_t;
865 using typename InfoBase_t::Iter_t;
866 using typename InfoBase_t::Value_t;
867 using typename InfoBase_t::Env_t;
868 using typename InfoBase_t::PEnv_t;
869 using typename InfoBase_t::PCont_t;
870 using typename InfoBase_t::PValue_t;
871
872 static void resize(void*,size_t) {
873 }
874 static void* feed(void *from, void *to, size_t size) {
875 PCont_t c = PCont_t(to);
876 PValue_t m = PValue_t(from);
877 for (size_t i=0; i<size; ++i, ++m)
878 c->set(i,*m);
879 return 0;
880 }
881 static int value_offset() {
882 return 0;
883 }
884 };
885
886} // namespace Detail
887
888// For (reasonable) backward compatibility:
889using namespace Detail;
890} // namespace ROOT
891
892#endif
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
#define c(i)
Definition: RSha256.hxx:101
#define e(i)
Definition: RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned int UInt_t
Definition: RtypesCore.h:46
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
#define TYPENAME
#define R__ASSERT(e)
Definition: TError.h:118
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)
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition: RVec.hxx:284
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...
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 &)=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)
auto * m
Definition: textangle.C:8
#define dest(otri, vertexptr)
Definition: triangle.c:1041