|
@@ -5,25 +5,18 @@
|
|
#include "bbtypeinfo.h"
|
|
#include "bbtypeinfo.h"
|
|
|
|
|
|
struct bbVariant{
|
|
struct bbVariant{
|
|
-
|
|
|
|
- template<class T,class R=typename T::bb_object_type> static bbObject *toObject( T *p ){
|
|
|
|
- return dynamic_cast<bbObject*>( p );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- template<class T> static bbObject *toObject( T const& ){
|
|
|
|
- bbRuntimeError( "Variant cast failed" );
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- template<class T,class C> static T castObject( bbObject *p,typename C::bb_object_type d=0 ){
|
|
|
|
- return dynamic_cast<T>( p );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- template<class T,class C> static T castObject(...){
|
|
|
|
- bbRuntimeError( "Variant cast failed" );
|
|
|
|
- return {};
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
+ template<class T> static bbObject *_getObject( T const& ){ bbRuntimeError( "Variant cast failed" );return 0; }
|
|
|
|
+ template<class T,class R=typename T::bb_object_type> static bbObject *_getObject( T *p ){ return dynamic_cast<bbObject*>( p ); }
|
|
|
|
+
|
|
|
|
+ template<class T> static int _getArrayLength( T const& ){ bbRuntimeError( "Variant is not an array" );return 0; }
|
|
|
|
+ template<class T> static bbVariant _getArrayElement( T const&,int index ){ bbRuntimeError( "Variant is not an array" );return {}; }
|
|
|
|
+ template<class T> static void _setArrayElement( T const&,int index,bbVariant value ){ bbRuntimeError( "Variant is not an array" ); }
|
|
|
|
+
|
|
|
|
+ template<class T,int D> static int _getArrayLength( bbArray<T,D> v ){ return v.length(); }
|
|
|
|
+ template<class T,int D> static bbVariant _getArrayElement( bbArray<T,D> v,int index );
|
|
|
|
+ template<class T,int D> static void _setArrayElement( bbArray<T,D> v,int index,bbVariant value );
|
|
|
|
+
|
|
struct RepBase{
|
|
struct RepBase{
|
|
|
|
|
|
int _refs=1;
|
|
int _refs=1;
|
|
@@ -42,10 +35,22 @@ struct bbVariant{
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ virtual int getArrayLength(){
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ virtual bbVariant getArrayElement( int index ){
|
|
|
|
+ return {};
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ virtual void setArrayElement( int index,bbVariant value ){
|
|
|
|
+ }
|
|
|
|
+
|
|
virtual bbVariant invoke( bbArray<bbVariant> params ){
|
|
virtual bbVariant invoke( bbArray<bbVariant> params ){
|
|
bbRuntimeError( "Variant is not invokable" );
|
|
bbRuntimeError( "Variant is not invokable" );
|
|
return {};
|
|
return {};
|
|
}
|
|
}
|
|
|
|
+
|
|
};
|
|
};
|
|
|
|
|
|
template<class T> struct Rep : public RepBase{
|
|
template<class T> struct Rep : public RepBase{
|
|
@@ -64,8 +69,21 @@ struct bbVariant{
|
|
}
|
|
}
|
|
|
|
|
|
virtual bbObject *getObject(){
|
|
virtual bbObject *getObject(){
|
|
- return toObject( value );
|
|
|
|
|
|
+ return _getObject( value );
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ virtual int getArrayLength(){
|
|
|
|
+ return _getArrayLength( value );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ virtual bbVariant getArrayElement( int index ){
|
|
|
|
+ return _getArrayElement( value,index );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ virtual void setArrayElement( int index,bbVariant evalue ){
|
|
|
|
+ _setArrayElement( value,index,evalue );
|
|
|
|
+ }
|
|
|
|
+
|
|
};
|
|
};
|
|
|
|
|
|
static RepBase _null;
|
|
static RepBase _null;
|
|
@@ -106,79 +124,96 @@ struct bbVariant{
|
|
return *this;
|
|
return *this;
|
|
}
|
|
}
|
|
|
|
|
|
- bbTypeInfo *getType()const{
|
|
|
|
-
|
|
|
|
- return _rep->getType();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- bbTypeInfo *getDynamicType()const{
|
|
|
|
-
|
|
|
|
- if( bbObject *obj=_rep->getObject() ) return obj->typeof();
|
|
|
|
-
|
|
|
|
- return _rep->getType();
|
|
|
|
|
|
+ template<class T,class R=typename T::bb_object_type> T *_get( T* const& )const{
|
|
|
|
+ bbObject *obj=_rep->getObject();
|
|
|
|
+ return dynamic_cast<T*>( obj );
|
|
}
|
|
}
|
|
|
|
|
|
- operator bool()const{
|
|
|
|
-
|
|
|
|
- return _rep!=&_null;
|
|
|
|
|
|
+ template<class T> T _get( T const& )const{
|
|
|
|
+ bbRuntimeError( "Variant cast failed" );
|
|
|
|
+ return {};
|
|
}
|
|
}
|
|
|
|
|
|
template<class T> T get()const{
|
|
template<class T> T get()const{
|
|
-
|
|
|
|
- Rep<T> *p=dynamic_cast<Rep<T>*>( _rep );
|
|
|
|
-
|
|
|
|
- if( p ) return p->value;
|
|
|
|
-
|
|
|
|
-// bbTypeInfo *type=bbGetType<T>();
|
|
|
|
-
|
|
|
|
-// if( type->kind=="Class" ){
|
|
|
|
-
|
|
|
|
- bbObject *obj=_rep->getObject();
|
|
|
|
-
|
|
|
|
- typedef typename detail::remove_pointer<T>::type C;
|
|
|
|
-
|
|
|
|
- return castObject<T,C>( obj );
|
|
|
|
-// }
|
|
|
|
-
|
|
|
|
- bbRuntimeError( "Variant cast failed" );
|
|
|
|
-
|
|
|
|
- return T{};
|
|
|
|
|
|
+ Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
|
|
|
|
+ if( !r ) return _get( *(T*)0 );
|
|
|
|
+ return r->value;
|
|
}
|
|
}
|
|
|
|
|
|
- template<class T> T *_ref( typename T::bb_object_type *p=0 )const{
|
|
|
|
-
|
|
|
|
|
|
+ template<class T,class R=typename T::bb_object_type> T *_ref( T** )const{
|
|
return get<T*>();
|
|
return get<T*>();
|
|
}
|
|
}
|
|
|
|
|
|
- template<class T> T *_ref( T *p=0 )const{
|
|
|
|
-
|
|
|
|
|
|
+ template<class T> T *_ref( T* )const{
|
|
Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
|
|
Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
|
|
-
|
|
|
|
if( !r ) bbRuntimeError( "Variant cast failed" );
|
|
if( !r ) bbRuntimeError( "Variant cast failed" );
|
|
-
|
|
|
|
return &r->value;
|
|
return &r->value;
|
|
}
|
|
}
|
|
|
|
|
|
template<class T> T *ref()const{
|
|
template<class T> T *ref()const{
|
|
|
|
+ return _ref<T>( 0 );
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ template<class T> T *_ref( typename T::bb_object_type *p )const{
|
|
|
|
+ return get<T>();
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ template<class T> T *_ref( T *p )const{
|
|
|
|
+ Rep<T> *r=dynamic_cast<Rep<T>*>( _rep );
|
|
|
|
+ if( !r ) bbRuntimeError( "Variant cast failed" );
|
|
|
|
+ return &r->value;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ template<class T> T *ref()const{
|
|
return _ref<T>( 0 );
|
|
return _ref<T>( 0 );
|
|
}
|
|
}
|
|
|
|
+ */
|
|
|
|
|
|
- int enumValue()const{
|
|
|
|
|
|
+ bbTypeInfo *getType()const{
|
|
|
|
+ return _rep->getType();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bbTypeInfo *getDynamicType()const{
|
|
|
|
+ if( bbObject *obj=_rep->getObject() ) return obj->typeof();
|
|
|
|
+ return _rep->getType();
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ operator bool()const{
|
|
|
|
+ return _rep!=&_null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int enumValue()const{
|
|
return getType()->getEnum( *this );
|
|
return getType()->getEnum( *this );
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ int getArrayLength(){
|
|
|
|
+ return _rep->getArrayLength();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bbVariant getArrayElement( int index ){
|
|
|
|
+ return _rep->getArrayElement( index );
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ void setArrayElement( int index,bbVariant value ){
|
|
|
|
+ _rep->setArrayElement( index,value );
|
|
|
|
+ }
|
|
};
|
|
};
|
|
|
|
|
|
inline void bbGCMark( const bbVariant &v ){
|
|
inline void bbGCMark( const bbVariant &v ){
|
|
-
|
|
|
|
v._rep->gcMark();
|
|
v._rep->gcMark();
|
|
}
|
|
}
|
|
|
|
|
|
inline int bbCompare( const bbVariant &x,const bbVariant &y ){
|
|
inline int bbCompare( const bbVariant &x,const bbVariant &y ){
|
|
-
|
|
|
|
return y._rep>x._rep ? -1 : x._rep>y._rep;
|
|
return y._rep>x._rep ? -1 : x._rep>y._rep;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+template<class T,int D> bbVariant bbVariant::_getArrayElement( bbArray<T,D> v,int index ){
|
|
|
|
+ return bbVariant( v[index] );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+template<class T,int D> void bbVariant::_setArrayElement( bbArray<T,D> v,int index,bbVariant value ){
|
|
|
|
+ v[index]=value.get<T>();
|
|
|
|
+}
|
|
|
|
+
|
|
#endif
|
|
#endif
|