12 #ifndef ROOT_TCollectionProxyInfo
13 #define ROOT_TCollectionProxyInfo
24 #include <forward_list>
31 #define TYPENAME typename
34 #define TYPENAME typename
40 template <
typename T>
class TStdBitsetHelper {
49 class TCollectionProxyInfo {
57 static const UInt_t fgIteratorArenaSize = 16;
66 template <
typename Cont_t,
typename value>
struct IteratorValue {
67 static void*
get(
typename Cont_t::iterator &iter) {
68 return (
void*)&(*iter);
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);
85 template <
typename Cont_t,
bool large = false>
87 typedef Cont_t *PCont_t;
88 typedef typename Cont_t::iterator iterator;
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());
95 static void* copy(
void *dest_arena,
const void *source_ptr) {
96 iterator *source = (iterator *)(source_ptr);
97 new (dest_arena) iterator(*source);
100 static void* next(
void *iter_loc,
const void *end_loc) {
101 iterator *end = (iterator *)(end_loc);
102 iterator *iter = (iterator *)(iter_loc);
104 void *result = IteratorValue<Cont_t, typename Cont_t::value_type>::get(*iter);
110 static void destruct1(
void *iter_ptr) {
111 iterator *start = (iterator *)(iter_ptr);
114 static void destruct2(
void *begin_ptr,
void *end_ptr) {
115 iterator *start = (iterator *)(begin_ptr);
116 iterator *end = (iterator *)(end_ptr);
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;
131 static void create(
void *coll,
void **begin_arena,
void **end_arena, TVirtualCollectionProxy*) {
132 PCont_t c = PCont_t(coll);
138 *begin_arena = &(*c->begin());
139 #ifdef R__VISUAL_CPLUSPLUS
140 *end_arena = &(*(c->end()-1)) + 1;
143 *end_arena = &(*c->end());
146 static void* copy(
void *dest,
const void *source) {
147 *(
void**)dest = *(
void**)(
const_cast<void*
>(source));
150 static void* next(
void * ,
const void * ) {
159 R__ASSERT(0 &&
"Intentionally not implemented, do not use.");
162 static void destruct1(
void * ) {
165 static void destruct2(
void * ,
void * ) {
170 template <
typename Cont_t>
struct Iterators<Cont_t, true > {
171 typedef Cont_t *PCont_t;
172 typedef typename Cont_t::iterator iterator;
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());
179 static void* copy(
void * ,
const void *source_ptr) {
180 iterator *source = (iterator *)(source_ptr);
181 void *iter =
new iterator(*source);
184 static void* next(
void *iter_loc,
const void *end_loc) {
185 iterator *end = (iterator *)(end_loc);
186 iterator *iter = (iterator *)(iter_loc);
188 void *result = IteratorValue<Cont_t, typename Cont_t::value_type>::get(*iter);
194 static void destruct1(
void *begin_ptr) {
195 iterator *start = (iterator *)(begin_ptr);
198 static void destruct2(
void *begin_ptr,
void *end_ptr) {
199 iterator *start = (iterator *)(begin_ptr);
200 iterator *end = (iterator *)(end_ptr);
217 EnvironBase(
const EnvironBase&);
218 EnvironBase &operator=(
const EnvironBase&);
220 EnvironBase() : fIdx(0), fSize(0), fObject(0), fStart(0), fTemp(0), fUseTemp(kFALSE), fRefCount(1), fSpace(0)
223 virtual ~EnvironBase() {}
231 Bool_t fLastValueVecBool;
236 template <
typename T>
struct Environ :
public EnvironBase {
237 Environ() : fIterator() {}
240 T& iter() {
return fIterator; }
241 static void *Create() {
242 return new Environ();
246 template <
class T,
class Q>
struct PairHolder {
250 PairHolder(
const PairHolder& c) : first(c.first), second(c.second) {}
251 virtual ~PairHolder() {}
253 PairHolder& operator=(
const PairHolder&);
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));
263 struct SfinaeHelper {
268 static size_t GetContainerSize(
const T& c) {
return c.size();}
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());}
285 template <
class T>
struct Type
286 :
public Address<TYPENAME T::const_reference>
289 typedef typename T::iterator Iter_t;
290 typedef typename T::value_type Value_t;
291 typedef Environ<Iter_t> Env_t;
292 typedef Env_t *PEnv_t;
293 typedef Cont_t *PCont_t;
294 typedef Value_t *PValue_t;
298 static inline PCont_t object(
void* ptr) {
299 return PCont_t(PEnv_t(ptr)->fObject);
301 static void* size(
void* env) {
302 PEnv_t e = PEnv_t(env);
303 e->fSize = SfinaeHelper::GetContainerSize(*PCont_t(e->fObject));
306 static void* clear(
void* env) {
307 object(env)->clear();
310 static void* first(
void* env) {
311 PEnv_t e = PEnv_t(env);
312 PCont_t c = PCont_t(e->fObject);
315 ::new(e->buff) Iter_t(c->begin());
317 e->fIterator = c->begin();
318 e->fSize = SfinaeHelper::GetContainerSize(*c);
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);
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){ }
328 if ( e->iter() == c->end() )
return 0;
329 TYPENAME T::const_reference ref = *(e->iter());
330 return Type<T>::address(ref);
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)
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);
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 )
351 static const bool fgLargeIterator =
sizeof(
typename Cont_t::iterator) > fgIteratorArenaSize;
352 typedef Iterators<Cont_t,fgLargeIterator> Iterators_t;
365 template <
class T>
struct Pushback :
public Type<T> {
367 typedef typename T::iterator Iter_t;
368 typedef typename T::value_type Value_t;
369 typedef Environ<Iter_t> Env_t;
370 typedef Env_t *PEnv_t;
371 typedef Cont_t *PCont_t;
372 typedef Value_t *PValue_t;
373 static void resize(
void* obj,
size_t n) {
374 PCont_t c = PCont_t(obj);
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)
384 static int value_offset() {
398 template <
class T>
struct Pushfront :
public Type<T> {
400 typedef typename T::iterator Iter_t;
401 typedef typename T::value_type Value_t;
402 typedef Environ<Iter_t> Env_t;
403 typedef Env_t *PEnv_t;
404 typedef Cont_t *PCont_t;
405 typedef Value_t *PValue_t;
406 static void resize(
void* obj,
size_t n) {
407 PCont_t c = PCont_t(obj);
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]);
415 for (
size_t i=0; i<size; ++i, --m){
420 static int value_offset() {
434 template <
class T>
struct Insert :
public Type<T> {
436 typedef typename T::iterator Iter_t;
437 typedef typename T::value_type Value_t;
438 typedef Environ<Iter_t> Env_t;
439 typedef Env_t *PEnv_t;
440 typedef Cont_t *PCont_t;
441 typedef Value_t *PValue_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)
449 static void resize(
void* ,
size_t ) {
452 static int value_offset() {
466 template <
class T>
struct MapInsert :
public Type<T> {
468 typedef typename T::iterator Iter_t;
469 typedef typename T::value_type Value_t;
470 typedef Environ<Iter_t> Env_t;
471 typedef Env_t *PEnv_t;
472 typedef Cont_t *PCont_t;
473 typedef Value_t *PValue_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)
481 static void resize(
void* ,
size_t ) {
484 static int value_offset() {
485 return ((
char*)&((PValue_t(0x1000))->second)) - ((
char*)PValue_t(0x1000));
491 const std::type_info &fInfo;
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)();
507 void (*fCreateIterators)(
void *collection,
void **begin_arena,
void **end_arena, TVirtualCollectionProxy *proxy);
512 void* (*fCopyIterator)(
void *dest,
const void *source);
517 void* (*fNext)(
void *iter,
const void *end);
523 void (*fDeleteSingleIterator)(
void *iter);
524 void (*fDeleteTwoIterators)(
void *begin,
void *end);
529 TCollectionProxyInfo(
const std::type_info& info,
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
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)
561 template <
class T>
static TCollectionProxyInfo* Generate(
const T&) {
567 PairHolder<TYPENAME T::Value_t, TYPENAME T::Value_t>* p =
568 (PairHolder<TYPENAME T::Value_t, TYPENAME T::Value_t>*)0x1000;
569 return new TCollectionProxyInfo(
typeid(TYPENAME T::Cont_t),
570 sizeof(TYPENAME T::Iter_t),
571 (((
char*)&p->second)-((
char*)&p->first)),
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);
590 template <
class T>
static TCollectionProxyInfo Get(
const T&) {
597 PairHolder<TYPENAME T::Value_t, TYPENAME T::Value_t>* p =
598 (PairHolder<TYPENAME T::Value_t, TYPENAME T::Value_t>*)0x1000;
599 return TCollectionProxyInfo(
typeid(TYPENAME T::Cont_t),
600 sizeof(TYPENAME T::Iter_t),
601 (((
char*)&p->second)-((
char*)&p->first)),
619 template <
class A>
struct TCollectionProxyInfo::Type<std::vector<Bool_t, A>>
620 :
public TCollectionProxyInfo::Address<typename std::vector<Bool_t, A>::const_reference>
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;
625 typedef Environ<Iter_t> Env_t;
626 typedef Env_t *PEnv_t;
627 typedef Cont_t *PCont_t;
628 typedef Value_t *PValue_t;
632 static inline PCont_t object(
void* ptr) {
633 return PCont_t(PEnv_t(ptr)->fObject);
635 static void* size(
void* env) {
636 PEnv_t e = PEnv_t(env);
637 e->fSize = PCont_t(e->fObject)->size();
640 static void* clear(
void* env) {
641 object(env)->clear();
644 static void* first(
void* env) {
645 PEnv_t e = PEnv_t(env);
646 PCont_t c = PCont_t(e->fObject);
649 ::new(e->buff) Iter_t(c->begin());
651 e->fIterator = c->begin();
652 e->fSize = c->size();
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){ }
662 static void* construct(
void*,
size_t) {
666 static void* collect(
void *coll,
void *array) {
667 PCont_t c = PCont_t(coll);
668 PValue_t m = PValue_t(array);
669 for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
670 ::
new(m) Value_t(*i);
673 static void destruct(
void*,
size_t) {
681 typedef typename Cont_t::iterator iterator;
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());
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);
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);
704 static void destruct1(
void *iter_ptr) {
705 iterator *start = (iterator *)(iter_ptr);
708 static void destruct2(
void *begin_ptr,
void *end_ptr) {
709 iterator *start = (iterator *)(begin_ptr);
710 iterator *end = (iterator *)(end_ptr);
715 typedef Iterators Iterators_t;
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;
723 typedef Environ<Iter_t> Env_t;
724 typedef Env_t *PEnv_t;
725 typedef Cont_t *PCont_t;
726 typedef Value_t *PValue_t;
728 static void resize(
void* obj,
size_t n) {
729 PCont_t c = PCont_t(obj);
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)
739 static int value_offset() {
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) {
754 template <
typename Bitset_t>
struct TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > :
public TCollectionProxyInfo::Address<const Bool_t &>
756 typedef Bitset_t Cont_t;
757 typedef std::pair<size_t,Bool_t> Iter_t;
758 typedef Bool_t Value_t;
759 typedef Environ<Iter_t> Env_t;
760 typedef Env_t *PEnv_t;
761 typedef Cont_t *PCont_t;
762 typedef Value_t *PValue_t;
766 static inline PCont_t object(
void* ptr) {
767 return PCont_t(PEnv_t(ptr)->fObject);
769 static void* size(
void* env) {
770 PEnv_t e = PEnv_t(env);
771 e->fSize = PCont_t(e->fObject)->size();
774 static void* clear(
void* env) {
775 object(env)->reset();
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 ;
783 e->fSize = c->size();
784 return &(e->fIterator.second);
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);
793 static void* construct(
void*,
size_t) {
797 static void* collect(
void *coll,
void *array) {
798 PCont_t c = PCont_t(coll);
799 PValue_t m = PValue_t(array);
800 for (
size_t i=0; i != c->size(); ++i, ++m )
804 static void destruct(
void*,
size_t) {
812 union PtrSize_t {
size_t fIndex;
void *fAddress; };
813 typedef std::pair<PtrSize_t,Bool_t> iterator;
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;
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);
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);
840 return &(iter->second);
842 static void destruct1(
void *iter_ptr) {
843 iterator *start = (iterator *)(iter_ptr);
846 static void destruct2(
void *begin_ptr,
void *end_ptr) {
847 iterator *start = (iterator *)(begin_ptr);
848 iterator *end = (iterator *)(end_ptr);
853 typedef Iterators Iterators_t;
856 template <
typename Bitset_t>
857 struct TCollectionProxyInfo::Pushback<Internal::TStdBitsetHelper<Bitset_t> > :
public TCollectionProxyInfo::Type<Internal::TStdBitsetHelper<Bitset_t> > {
858 using InfoBase_t = 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;
867 static void resize(
void*,
size_t) {
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)
876 static int value_offset() {
884 using namespace Detail;