From: <baz...@us...> - 2008-02-25 00:39:46
|
Revision: 8096 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8096&view=rev Author: bazaarmagetron Date: 2008-02-24 16:39:44 -0800 (Sun, 24 Feb 2008) Log Message: ----------- Manuel Moos: Repaired enum references. Modified Paths: -------------- clio/trunk/clio/clio/Makefile.am clio/trunk/clio/clio/argumentquality.hpp clio/trunk/clio/clio/clio.hpp clio/trunk/clio/clio/dataconversion.cpp clio/trunk/clio/clio/dataconversion_extended.cpp clio/trunk/clio/clio/dataconversion_extended.hpp clio/trunk/clio/clio/enum.hpp clio/trunk/clio/clio/helptest.hpp clio/trunk/clio/clio/macros.hpp clio/trunk/clio/clio/proxy.hpp clio/trunk/clio/clio/std_container.hpp clio/trunk/clio/clio/typetraits.hpp Added Paths: ----------- clio/trunk/clio/clio/primitiveproxy.cpp clio/trunk/clio/clio/primitiveproxy.hpp Property Changed: ---------------- clio/trunk/clio/ Property changes on: clio/trunk/clio ___________________________________________________________________ Name: bzr:revision-info - timestamp: 2008-02-24 01:14:25.210000038 +0100 committer: Manuel Moos <z-...@us...> properties: branch-nick: clio + timestamp: 2008-02-24 17:14:54.890000105 +0100 committer: Manuel Moos <z-...@us...> properties: branch-nick: clio Name: bzr:file-ids - + clio/primitiveproxy.hpp primitiveproxy.hpp-20080224161453-yaim302iihdd19qa-2 clio/primitiveproxy.cpp primitiveproxy.cpp-20080224161453-yaim302iihdd19qa-1 Name: bzr:revision-id:v3-list-QlpoOTFBWSZTWZvbKhsAAAdRgAAQABK6798QIABURMgAAaeoNT1TxT1DQbKaeobXKiyAmlWT7Y5MkdJOtXDtB7w7DOGFBHiOBxaUIu7HQyyQSvxdyRThQkJvbKhs - 4 z-...@us...-20080222202821-mkuiwckx41jof2gj 5 z-...@us...-20080222202957-htiysaaxkiroqd7e 6 z-...@us...-20080222211806-jc50b77qlgn2dp8j 7 z-...@us...-20080222215601-p8y78c77ncvq5eb1 8 z-...@us...-20080222223809-mmh9wh6yzrdm7oa1 9 z-...@us...-20080222232123-uhnuqd9db0p27rkf 10 z-...@us...-20080222232154-k64q4ee9zuq5r2jp 11 z-...@us...-20080222234236-ny0hc8lwybz73rv6 12 z-...@us...-20080223000039-566psft2c96236kw 13 z-...@us...-20080223000530-4mtket15l6oeo1ju 14 z-...@us...-20080223001030-5t86d3u3bidpoq6r 15 z-...@us...-20080223002857-qvx8z72tmsoguku0 16 z-...@us...-20080223004917-abqn3vdfqb1euyzc 17 z-...@us...-20080223010025-h0nul9yntjvutdbq 18 z-...@us...-20080223013357-1nzhrjwjr4g0h7g9 19 z-...@us...-20080223015240-btmt95d1vvlip4gl 20 z-...@us...-20080223124731-dlwuagon76gq2o3g 21 z-...@us...-20080223133015-0hjqyrki59ydwdcv 22 z-...@us...-20080223135113-icwd4g99yev9n0u2 23 z-...@us...-20080223152916-8rm942q1rmjlueca 24 z-...@us...-20080223174524-3lb2wm6tt5nytd4b 25 z-...@us...-20080223174610-gwmr3fn8456rwvmg 26 z-...@us...-20080223183115-ub0hshkf3zfs69ko 27 z-...@us...-20080223185539-cvhsltp2u12d5lgc 28 z-...@us...-20080223211352-km18u9bp9qhufyta 29 z-...@us...-20080223225132-94n2bwt307fujbg4 30 z-...@us...-20080223234541-mqp3d64uyn3no98y 31 z-...@us...-20080223235231-5lshcanhqlkwv36n 32 z-...@us...-20080224001425-n6xziwrp0hh3nz2f + 4 z-...@us...-20080222202821-mkuiwckx41jof2gj 5 z-...@us...-20080222202957-htiysaaxkiroqd7e 6 z-...@us...-20080222211806-jc50b77qlgn2dp8j 7 z-...@us...-20080222215601-p8y78c77ncvq5eb1 8 z-...@us...-20080222223809-mmh9wh6yzrdm7oa1 9 z-...@us...-20080222232123-uhnuqd9db0p27rkf 10 z-...@us...-20080222232154-k64q4ee9zuq5r2jp 11 z-...@us...-20080222234236-ny0hc8lwybz73rv6 12 z-...@us...-20080223000039-566psft2c96236kw 13 z-...@us...-20080223000530-4mtket15l6oeo1ju 14 z-...@us...-20080223001030-5t86d3u3bidpoq6r 15 z-...@us...-20080223002857-qvx8z72tmsoguku0 16 z-...@us...-20080223004917-abqn3vdfqb1euyzc 17 z-...@us...-20080223010025-h0nul9yntjvutdbq 18 z-...@us...-20080223013357-1nzhrjwjr4g0h7g9 19 z-...@us...-20080223015240-btmt95d1vvlip4gl 20 z-...@us...-20080223124731-dlwuagon76gq2o3g 21 z-...@us...-20080223133015-0hjqyrki59ydwdcv 22 z-...@us...-20080223135113-icwd4g99yev9n0u2 23 z-...@us...-20080223152916-8rm942q1rmjlueca 24 z-...@us...-20080223174524-3lb2wm6tt5nytd4b 25 z-...@us...-20080223174610-gwmr3fn8456rwvmg 26 z-...@us...-20080223183115-ub0hshkf3zfs69ko 27 z-...@us...-20080223185539-cvhsltp2u12d5lgc 28 z-...@us...-20080223211352-km18u9bp9qhufyta 29 z-...@us...-20080223225132-94n2bwt307fujbg4 30 z-...@us...-20080223234541-mqp3d64uyn3no98y 31 z-...@us...-20080223235231-5lshcanhqlkwv36n 32 z-...@us...-20080224001425-n6xziwrp0hh3nz2f 33 z-...@us...-20080224161454-lyyn0grllfn5qx8w Modified: clio/trunk/clio/clio/Makefile.am =================================================================== --- clio/trunk/clio/clio/Makefile.am 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/Makefile.am 2008-02-25 00:39:44 UTC (rev 8096) @@ -27,6 +27,7 @@ nocopy.cpp\ objectwrapperaware.cpp\ objectwrapper.cpp\ +primitiveproxy.cpp\ property.cpp\ proxy.cpp\ security.cpp\ @@ -81,6 +82,7 @@ objectwrapperaware.hpp\ objectwrapper.hpp\ property.hpp\ +primitiveproxy.hpp\ proxy.hpp\ security.hpp\ state.hpp\ Modified: clio/trunk/clio/clio/argumentquality.hpp =================================================================== --- clio/trunk/clio/clio/argumentquality.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/argumentquality.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -66,6 +66,8 @@ Quality_Perfect = 0, // all arguments are perfect fits Quality_Upcast, // a C++ argument is given of a derived class of the expected class Quality_Conversion, // conversion is required + Quality_Box, // required boxing in a wrapper + Quality_Void, // conversion to void * or IoObject * required Quality_NoMatch, // can't match Quality_Max }; Modified: clio/trunk/clio/clio/clio.hpp =================================================================== --- clio/trunk/clio/clio/clio.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/clio.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -2,5 +2,6 @@ #define CLIO_CLIO_H #include "macros.hpp" +#include "dataconversion_extended.hpp" #endif Modified: clio/trunk/clio/clio/dataconversion.cpp =================================================================== --- clio/trunk/clio/clio/dataconversion.cpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/dataconversion.cpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -1,6 +1,6 @@ #include "dataconversion.hpp" +#include "dataconversion_extended.hpp" - #include <sstream> namespace clio Modified: clio/trunk/clio/clio/dataconversion_extended.cpp =================================================================== --- clio/trunk/clio/clio/dataconversion_extended.cpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/dataconversion_extended.cpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -106,7 +106,7 @@ } #define CLIO_CREATE_PRIMITIVE( INT, NAME ) \ -CLIO_INSTANTIATE_TEMPLATE(clio::PrimitiveProxy,(1,(INT)), NAME ) +CLIO_INSTANTIATE_TEMPLATE(clio::PrimitiveWrapper,(1,(INT)), NAME ) #define CLIO_CREATE_PRIMITIVE_INT( INT, NAME ) \ CLIO_CREATE_PRIMITIVE( INT, NAME ); \ Modified: clio/trunk/clio/clio/dataconversion_extended.hpp =================================================================== --- clio/trunk/clio/clio/dataconversion_extended.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/dataconversion_extended.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -132,6 +132,7 @@ #include "objectwrapperaware.hpp" #include "codeinjection.hpp" #include "ichained.hpp" +#include "primitiveproxy.hpp" // now comes the really fancy stuff. Here, we can already use clio's full wrapping power to // use C++ wrapper types as the objects converted to Io. @@ -141,6 +142,8 @@ namespace dataconversion { + +#if 0 // For example this little beast: it wraps const references to primitives // (and other objects) so the receiver on the Io side can get them. // This is really just for primitives. Anything that may cause memory allocation @@ -274,25 +277,27 @@ }; extern char const * primitveProxyCode; +#endif } -struct PrimitiveProxyNoMaster{}; +// struct PrimitiveProxyNoMaster{}; // let primitives be handled by their wrapper for template arguments template< class T > struct clioPrivate_classToTypeBase< T, true > { - typedef dataconversion::PrimitiveProxy<T> Type; + typedef typename PrimitiveWrapper<T>::GETTER Type; }; } #define CLIO_INSTANTIATE_PRIMITIVE_PROXY( INT, NAME ) \ -CLIO_CLASSNAME_EX( clio::dataconversion::PrimitiveProxy<const INT>, "Const" NAME, clio::IClassInfo::Name_IoRaw ); \ -CLIO_CLASSNAME_EX( clio::dataconversion::PrimitiveProxy<INT>, NAME, clio::IClassInfo::Name_IoRaw ) +CLIO_CLASSNAME_EX( clio::PrimitiveWrapper<const INT>, "Const" NAME, clio::IClassInfo::Name_IoRaw ); \ +CLIO_CLASSNAME_EX( clio::PrimitiveWrapper<INT>, NAME, clio::IClassInfo::Name_IoRaw ) #define CLIO_INSTANTIATE_PRIMITIVE( INT, NAME ) \ -CLIO_INSTANTIATE_PRIMITIVE_PROXY( INT, NAME ); \ +CLIO_INSTANTIATE_PRIMITIVE_PROXY( INT, NAME );\ +CLIO_CONVERTAS_PROXY_REF( INT, PrimitiveProxy );\ CLIO_IO_COMPLETE_CLASSNAME( INT, "Clio " NAME ) #define CLIO_INSTANTIATE_PRIMITIVE_INT( INT, NAME ) \ @@ -302,7 +307,8 @@ CLIO_INSTANTIATE_PRIMITIVE_INT( long int, "LongInt" ); CLIO_INSTANTIATE_PRIMITIVE_INT( int, "Int" ); CLIO_INSTANTIATE_PRIMITIVE_INT( short int, "ShortInt" ); -CLIO_INSTANTIATE_PRIMITIVE_INT( char, "Char" ); +CLIO_INSTANTIATE_PRIMITIVE_PROXY( char, "Char" ); +CLIO_INSTANTIATE_PRIMITIVE_PROXY( unsigned char, "UnsignedChar" ); CLIO_INSTANTIATE_PRIMITIVE_PROXY( std::string, "Strng" ); CLIO_INSTANTIATE_PRIMITIVE( double, "Double" ); @@ -310,6 +316,7 @@ #undef CLIO_INSTANTIATE_PRIMITIVE +#if 0 CLIO_TEMPLATE_CLASS_EX( clio::dataconversion::PrimitiveProxyConstBase, (1,(class)), "ConstRef" ) { CLIO_CLASS_NAMESPACE( "clio" ); @@ -338,6 +345,7 @@ } CLIO_TEMPLATE_CLASS_NOMASTER( clio::dataconversion::PrimitiveProxy, (1,(class)), clio::PrimitiveProxyNoMaster ); +#endif namespace clio { @@ -348,7 +356,8 @@ // a primitiveProxy for that class is returned. template< class T > struct DataConverterPointerImplementationBase< T, false > { - typedef PrimitiveProxy< T > Proxy; + typedef PrimitiveWrapper< T > Wrapper; + typedef typename Wrapper::GETTER Proxy; typedef ClassInfo< Proxy > ClassInfo; typedef T * Converted; @@ -362,7 +371,7 @@ Proxy * proxy = DataConverterPointerImplementationBase< Proxy, true >::FromIo( from, call, thrower ); if ( !proxy ) thrower.Throw( "Only prototype found, but instance expected"); - return &proxy->GetTarget(); + return &proxy->Get(); } catch( ... ) { @@ -371,12 +380,18 @@ // convert the object as a regular value T value( DataConverterManager<T>::FromIo( from, call, thrower ) ); - // note that slight conversion was required (don't lower the quality class, though) - call.quality.conversionSteps++; + // note that boxing was required + if ( call.quality.quality < ArgumentQuality::Quality_Box ) + { + call.quality.quality = ArgumentQuality::Quality_Box; + } + else + { + call.quality.conversionSteps++; + } // create new proxy object holding a copy of the value - Proxy * p = new Proxy( & value ); - p->Detach(); + Proxy * p = new Wrapper( & value ); // make the object know to and owned by Io so it gets deleted later IoObject * object = ClassInfo::Get().FetchIoObject( p, IoObject_state(from), ObjectWrapper::OwnedByIo ); @@ -385,7 +400,7 @@ IoState_stackRetain_( IoObject_state(from), object ); // return a refernece to the held data - return &p->GetTarget(); + return &p->Get(); } catch( ... ){} @@ -396,7 +411,7 @@ static IoObject * ToIo( IoState * state, T * from, DataConversionCall const & call ) { - return ClassInfo::Get().FetchIoObject( new Proxy( from ), state, ObjectWrapper::OwnedByIo ); + return ClassInfo::Get().FetchIoObject( new Wrapper( from ), state, ObjectWrapper::OwnedByIo ); } }; Modified: clio/trunk/clio/clio/enum.hpp =================================================================== --- clio/trunk/clio/clio/enum.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/enum.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -2,6 +2,8 @@ #define CLIO_ENUM_H #include "macros.hpp" +#include "dataconversion_extended.hpp" +#include "primitiveproxy.hpp" namespace clio { @@ -88,16 +90,29 @@ // used for primitives which wraps the real enum object in something that has // a "set" method where you can change the value. That is not available as a regular // class method. - typedef dataconversion::DataConverterPointerImplementationBase< E, false > PointerImplementation; - typedef dataconversion::DataConverterReference< E &, PointerImplementation > ReferenceConverter; - typedef dataconversion::DataConverterPointer< E *, PointerImplementation > PointerConverter; + //typedef dataconversion::DataConverterPointerImplementationBase< E, false > PointerImplementation; + //typedef dataconversion::DataConverterReference< E &, PointerImplementation > ReferenceConverter; + //typedef dataconversion::DataConverterPointer< E *, PointerImplementation > PointerConverter; + + //typedef dataconversion::DataConverterReference< E &, PointerImplementation > ReferenceConverter; + //typedef dataconversion::DataConverterPointer< E *, PointerImplementation > PointerConverter; + + typedef dataconversion::DataConverterProxy< E &, PrimitiveProxy< Proxy< E > > > ReferenceConverter; + typedef dataconversion::DataConverterProxy< E *, PrimitiveProxy< Proxy< E > > > PointerConverter; + dataconversion::DataConverterOverrider< E &, ReferenceConverter >::Register(); dataconversion::DataConverterOverrider< E *, PointerConverter >::Register(); + + // instantiate reference wrapper + clio::ClassInfo< PrimitiveWrapper< CLASS > >::Get(); } }; } +// CLIO_CONVERTAS_PROXY_REF( ENUM, PrimitiveProxy ); + + // macro to define an enum. Works just like CLIO_CLASS*, all macros legal there // also work in here. #define CLIO_ENUM_EX( ENUM, USERNAME ) \ Modified: clio/trunk/clio/clio/helptest.hpp =================================================================== --- clio/trunk/clio/clio/helptest.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/helptest.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -1,7 +1,7 @@ #include <iostream> #include <fstream> -#include "macros.hpp" +#include "clio.hpp" #include "state.hpp" #include "gcpointer.hpp" Modified: clio/trunk/clio/clio/macros.hpp =================================================================== --- clio/trunk/clio/clio/macros.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/macros.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -493,6 +493,4 @@ #define CLIO_EXTEND_PROTECTED(FUNCTION) CLIO_EXTEND_PROTECTED_EX(FUNCTION,,"") #define CLIO_OVERRIDE_PRIVATE(FUNCTION,DISAMBIGUATION) CLIO_OVERRIDE_PRIVATE_EX(FUNCTION,DISAMBIGUATION,"") -#include "dataconversion_extended.hpp" - #endif Added: clio/trunk/clio/clio/primitiveproxy.cpp =================================================================== --- clio/trunk/clio/clio/primitiveproxy.cpp (rev 0) +++ clio/trunk/clio/clio/primitiveproxy.cpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -0,0 +1,19 @@ +#include "primitiveproxy.hpp" + +namespace clio +{ + +char const * primitiveProxyCode = +"print := method( get print )\n" +"== := method( other, get ==(other) )\n" +"asString := method( get asString )\n" +"asSimpleString := method( get asSimpleString )\n" +"hasSlot := method( s, get hasSlot(s) )\n" +"forward := method( return get doMessage(call message) ) \n" +; + +// specialize default constructor for strings +template<> PrimitiveWrapper< std::string >::PrimitiveWrapper(){} + +} + Added: clio/trunk/clio/clio/primitiveproxy.hpp =================================================================== --- clio/trunk/clio/clio/primitiveproxy.hpp (rev 0) +++ clio/trunk/clio/clio/primitiveproxy.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -0,0 +1,160 @@ +#ifndef CLIO_PRIMITIVEPROXY_H +#define CLIO_PRIMITIVEPROXY_H + +#include "proxy.hpp" + +namespace clio +{ + +template< class PRIMITIVE > class PrimitiveWrapper; + +// proxy for primitives, const version +template < class BASE > class ConstPrimitiveProxy: public BASE +{ +public: + typedef typename BASE::ORIGINAL Primitive; + + explicit ConstPrimitiveProxy( Primitive & primitive ) + : BASE( primitive ) + {} + + explicit ConstPrimitiveProxy( Primitive * primitive ) + : BASE( primitive ) + {} + + ConstPrimitiveProxy() + {} + + typedef PrimitiveWrapper<Primitive> WRAPPER; + + // clones the object as a wrapper + WRAPPER * clone() const; + + // gets the primitive + Primitive get() const + { + return this->Get(); + } +}; + +// proxy for primitives, non-const version +template< class BASE > class PrimitiveProxy: public ConstPrimitiveProxy< BASE > +{ +public: + typedef typename BASE::ORIGINAL Primitive; + + explicit PrimitiveProxy( Primitive & primitive ) + : ConstPrimitiveProxy< BASE >( primitive ) + {} + + explicit PrimitiveProxy( Primitive * primitive ) + : ConstPrimitiveProxy< BASE >( primitive ) + {} + + PrimitiveProxy() + {} + + void set( Primitive primitive ) + { + this->Get() = primitive; + } +}; + +// select the correct base wrapper +template< class T > +struct PrimitiveProxySelect +{ + typedef PrimitiveProxy< Wrapper< T > > Proxy; +}; + +template< class T > +struct PrimitiveProxySelect< const T > +{ + typedef ConstPrimitiveProxy< Wrapper< const T > > Proxy; +}; + +// wrapper for primitives +template< class T > class PrimitiveWrapper: public PrimitiveProxy< Wrapper< typename TestConst< T >::NoConst > > +{ +public: + typedef PrimitiveProxy< Wrapper< typename TestConst< T >::NoConst > > BASE; + + typedef typename BASE::Primitive Primitive; + + PrimitiveWrapper( PrimitiveWrapper const & other ) + { + this->Get() = other.Get(); + } + + explicit PrimitiveWrapper( Primitive const & primitive ) + { + this->Get() = primitive; + } + + explicit PrimitiveWrapper( Primitive const * primitive ) + { + if ( !primitive ) + { + throw Exception( "Expected primitive, got nil" ); + } + this->Get() = *primitive; + } + + PrimitiveWrapper() + { + // primitives should be initialized to 0 + this->Get() = static_cast< T >( 0 ); + } +}; + +// specialize default constructor for strings +template<> PrimitiveWrapper< std::string >::PrimitiveWrapper(); + +template< class BASE > +typename ConstPrimitiveProxy<BASE>::WRAPPER * ConstPrimitiveProxy<BASE>::clone() const +{ + return new WRAPPER( this->Get() ); +} + +struct PrimitiveProxyNoMaster{}; +extern char const * primitiveProxyCode; + +} + +#include "macros.hpp" + +CLIO_TEMPLATE_CLASS_SET_DEFAULTCONSTRUCTOR( clio::ConstPrimitiveProxy, (1,(class)), false ); + +CLIO_TEMPLATE_CLASS( clio::ConstPrimitiveProxy, (1,(class))) +{ + CLIO_CLASS_BASE( T1 ); + + CLIO_METHOD( get ).NonBreaking(); + CLIO_METHOD( clone ).TransferOwnership(); + + CLIO_INJECTCODE( clio::primitiveProxyCode ); +} + +CLIO_TEMPLATE_CLASS( clio::PrimitiveProxy, (1,(class))) +{ + CLIO_CLASS_BASE( clio::ConstPrimitiveProxy<T1> ); + + CLIO_METHOD( set ); + + CLIO_INJECTCODE( clio::primitiveProxyCode ); +} + +CLIO_TEMPLATE_CLASS_SET_DEFAULTCONSTRUCTOR( clio::PrimitiveWrapper, (1,(class)), true ); +CLIO_TEMPLATE_CLASS_EX( clio::PrimitiveWrapper, (1,(class)), "Ref" ) +{ + typedef typename CLASS::BASE BASE; + CLIO_CLASS_BASE( BASE ); + CLIO_CONSTRUCTOR_CUSTOM( (1,(T1)) ); + + CLIO_INJECTCODE( clio::primitiveProxyCode ); +} + +CLIO_TEMPLATE_CLASS_NOMASTER( clio::PrimitiveWrapper, (1,(class)), clio::PrimitiveProxyNoMaster ); + +#endif + Modified: clio/trunk/clio/clio/proxy.hpp =================================================================== --- clio/trunk/clio/clio/proxy.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/proxy.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -6,6 +6,7 @@ #include "dataconversion.hpp" #include <sstream> +#include <iostream> namespace clio { @@ -17,6 +18,7 @@ public: typedef T ORIGINAL; typedef WrapperBaseConst GETTER; + typedef ORIGINAL & GETRESULT; typedef WrapperBaseConst< const T > BASE; // returns the original object @@ -35,6 +37,7 @@ { public: typedef T ORIGINAL; + typedef ORIGINAL const & GETRESULT; typedef WrapperBaseConst GETTER; typedef IChained BASE; @@ -72,7 +75,7 @@ virtual ORIGINAL & DoGet() = 0; }; -// Proxy objects. ORIGINAL should be the raw type of the wrapped object, the +// Proxy objects. ORIGINAL should be the raw type of the wrapped object. template< class ORIGINAL > class Proxy: public WrapperBase< ORIGINAL > { @@ -221,22 +224,85 @@ template< class ORIGINAL, class PROXY > class DataConverterProxy: public DataConverterDefs< ORIGINAL > { public: - typedef typename PROXY::GETTER GETTER; + typedef typename PROXY::GETTER GETTER; // what we expect from Io + typedef typename GETTER::ORIGINAL ORIGINAL_BASE; // the raw base type + typedef typename GETTER::GETRESULT GETRESULT; // return type of GETTER::Get() typedef DataConverterDefs< ORIGINAL > Base; typedef DataConverterDefs< typename GETTER::ORIGINAL > Base2; typedef typename Base::TArg TArg; typedef typename Base::Converted Converted; + typedef DataConverterManager< ORIGINAL_BASE > IMPL_ORIGINAL; typedef DataConverterReference< GETTER &, DataConverterPointerImplementation< GETTER > > IMPL_GET; typedef DataConverterReference< PROXY &, DataConverterPointerImplementation< PROXY > > IMPL_SET; - static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) + static GETRESULT FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower, BoolToType<true> const & isConst ) { + try + { + GETTER & proxy = IMPL_GET::FromIo( from, call, thrower ); + return proxy.Get(); + } + catch( ... ) + { + try + { + // try to box whatever was there + ORIGINAL_BASE value( IMPL_ORIGINAL::FromIo( from, call, thrower ) ); + + // note that boxing was required + if ( call.quality.quality < ArgumentQuality::Quality_Box ) + { + call.quality.quality = ArgumentQuality::Quality_Box; + } + else + { + call.quality.conversionSteps++; + } + + // create new proxy object holding a copy of the value + PROXY * p = new PROXY( value ); + + // make the object know to and owned by Io so it gets deleted later + IoObject * object = ClassInfo< PROXY >::Get().FetchIoObject( p, IoObject_state(from), ObjectWrapper::OwnedByIo ); + + // but not before we leave here + IoState_stackRetain_( IoObject_state(from), object ); + + // return a refernece to the held data + return p->Get(); + } + catch(...){} // ignore errors in the block above + throw; // instead, rethrow the original error + } + } + + static GETRESULT FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower, BoolToType<false> const & isConst ) + { GETTER & proxy = IMPL_GET::FromIo( from, call, thrower ); return proxy.Get(); } + // check whether we can safely box an incoming object. + // plain values are OK, and const pointers and references + enum { + CanBox = + ( !TestPointer< ORIGINAL >::IsPointer && + !TestReference< ORIGINAL >::IsReference ) + || + ( TestPointer< ORIGINAL >::IsPointer && + TestConst< typename TestPointer< ORIGINAL >::NoPointer >::IsConst ) + || + ( TestReference< ORIGINAL >::IsReference && + TestConst< typename TestReference< ORIGINAL >::NoReference >::IsConst ) + }; + + static Converted FromIo( IoObject * from, DataConversionCall const & call, IExceptionThrower const & thrower ) + { + return TransformReference< Converted >::Transform( FromIo( from, call, thrower, BoolToType< CanBox >() ) ); + } + static void CheckType( IChained const & ){} static inline IoObject * ToIo( IoState * state, TArg from, DataConversionCall const & call ) @@ -288,8 +354,8 @@ CLIO_CLASS_BASE( clio::WrapperBase< T1 > ); } -#define CLIO_CONVERTAS_PROXY( CLASS, PROXY ) namespace clio{ namespace dataconversion{ \ -template<> struct DataConverterManager< CLASS >: public DataConverterProxy< CLASS, Proxy< PROXY > >{}; \ +#define CLIO_CONVERTAS_PROXY( CLASS, CONST, INDIRECTION, PROXY ) namespace clio{ namespace dataconversion{ \ +template<> struct DataConverterManager< CLASS CONST INDIRECTION >: public DataConverterProxy< CLASS CONST INDIRECTION, PROXY< Proxy< CLASS CONST > > >{}; \ }}CLIO_FORCESEMICOLON(proxy1) #define CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, CONST, INDIRECTION, SIGNATURE, PROXY ) namespace clio{ namespace dataconversion{ \ @@ -300,6 +366,18 @@ PROXY< Proxy< CLASS CLIO_TEMPLATE_ARGLIST_COMPLETE(SIGNATURE) CONST > > >{}; \ }}CLIO_FORCESEMICOLON(proxy2) +// convesion of (const) &/* arguments +#define CLIO_CONVERTAS_PROXY_REF( CLASS, PROXY ) \ +CLIO_CONVERTAS_PROXY( CLASS, ,& , PROXY ); \ +CLIO_CONVERTAS_PROXY( CLASS,const ,& , Const##PROXY ); \ +CLIO_CONVERTAS_PROXY( CLASS, ,* , PROXY ); \ +CLIO_CONVERTAS_PROXY( CLASS,const ,* , Const##PROXY ) + +// convesion of (const) &/* arguments +#define CLIO_CONVERTAS_PROXY_COMPLETE( CLASS, PROXY ) \ +CLIO_CONVERTAS_PROXY( CLASS,,, PROXY ); \ +CLIO_CONVERTAS_PROXY_REF( CLASS, PROXY ) \ + // complete convesion of (const) &/* arguments #define CLIO_CONVERTAS_PROXY_TEMPLATE_COMPLETE( CLASS, SIGNATURE, PROXY ) \ CLIO_CONVERTAS_PROXY_TEMPLATE( CLASS, , , SIGNATURE, PROXY ); \ Modified: clio/trunk/clio/clio/std_container.hpp =================================================================== --- clio/trunk/clio/clio/std_container.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/std_container.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -2,7 +2,6 @@ #define CLIO_STD_CONTAIENR_H #include "proxy.hpp" -#include "macros.hpp" #include "gcpointer.hpp" #include <vector> @@ -140,6 +139,9 @@ extern char const * vectorProxyCodeConst; } +#include "macros.hpp" +#include "dataconversion_extended.hpp" + CLIO_TEMPLATE_CLASS_SET_DEFAULTCONSTRUCTOR( clio::ConstVectorProxy, (1,(class)), false ); CLIO_TEMPLATE_CLASS( clio::ConstVectorProxy, (1,(class))) Modified: clio/trunk/clio/clio/typetraits.hpp =================================================================== --- clio/trunk/clio/clio/typetraits.hpp 2008-02-24 11:44:10 UTC (rev 8095) +++ clio/trunk/clio/clio/typetraits.hpp 2008-02-25 00:39:44 UTC (rev 8096) @@ -76,6 +76,24 @@ }; */ +// does harmless pointer/reference transformations +template< class T > struct TransformReference +{ + static T Transform( T in ){ return in; } +}; + +template< class T > struct TransformReference< T & > +{ + static T & Transform( T & in ){ return in; } + static T & Transform( T * in ){ assert( in ); return *in; } +}; + +template< class T > struct TransformReference< T * > +{ + static T * Transform( T & in ){ return ∈ } + static T * Transform( T * in ){ return in; } +}; + // class storing a temporary object template< class T > class TempStorage { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |