Skip to content

Commit 7a68787

Browse files
Add in a has_index_operator and has_size type traits.
RESTProcess uses this to support operator[] in python or @elem. has_index_operator needs to be marked up manually, alas, as I couldn't figure out how to SFINAE it.
1 parent 2f5bb25 commit 7a68787

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

RESTProcess_base.h

+30
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,36 @@ namespace classdesc
482482
bool isObject() const override {return true;}
483483
const object* getConstClassdescObject() override {return getClassdescObjectImpl(obj);}
484484
bool isConst() const override {return std::is_const<T>::value;}
485+
size_t size() const override {
486+
if constexpr (is_class<T>::value)
487+
if constexpr (has_size<T>::value)
488+
return obj.size();
489+
return 0;
490+
}
491+
RPPtr getElem(const REST_PROCESS_BUFFER& b) override {
492+
if constexpr (is_class<T>::value)
493+
if constexpr (has_index_operator<T>::value)
494+
{
495+
size_t index; b>>index;
496+
return makeRESTProcessRef(obj[index]);
497+
}
498+
return RESTProcessBase::getElem(b);
499+
}
500+
/// sets element indexed/keyed by \a index to \a value
501+
/// @return updated element
502+
RPPtr setElem(const REST_PROCESS_BUFFER& b, const REST_PROCESS_BUFFER& value) override
503+
{
504+
if constexpr (is_class<T>::value && !is_const<T>::value)
505+
if constexpr (has_index_operator<T>::value)
506+
{
507+
size_t index; b>>index;
508+
value>>obj[index];
509+
return makeRESTProcessRef(obj[index]);
510+
}
511+
return RESTProcessBase::setElem(b,value);
512+
}
513+
514+
485515
};
486516

487517
/// same as \a RESTProcessObject, but internally stores the object. T must be copy constructible or moveable

classdesc.h

+16
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,23 @@ namespace classdesc
486486
push_back(T& x, const typename T::value_type& v) {}
487487

488488

489+
CLASSDESC_HAS_MEMBER(size);
490+
template <class T> struct has_size: public has_member_size<T,size_t (T::*)()const> {};
491+
CLASSDESC_HAS_MEMBER(value_type);
492+
template <class T> struct has_value_type: public has_member_value_type<T,size_t (T::*)()const> {};
493+
494+
// doesn't quite work :(
495+
// template <class T>
496+
// struct has_index_operator
497+
// {
498+
// template <class U, decltype(&U::operator[])> struct SFINAE {};
499+
// template <class U> static char test(SFINAE<U,&U::operator[]>*);
500+
// template <class U> static int test(...);
501+
// const static bool value=sizeof(test<T>(0))==sizeof(char);
502+
// };
489503

504+
// specialise this to enable python indexing
505+
template <class T> struct has_index_operator: public false_type {};
490506

491507
// template <class T>
492508
// typename enable_if<is_sequence<T>,void>::T

0 commit comments

Comments
 (0)