From: <baz...@us...> - 2008-02-26 01:03:12
|
Revision: 8125 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=8125&view=rev Author: bazaarmagetron Date: 2008-02-25 17:03:10 -0800 (Mon, 25 Feb 2008) Log Message: ----------- Manuel Moos: Yay, wrappers now unbox themselves automatically. Modified Paths: -------------- clio/trunk/clio/clio/primitiveproxy.hpp clio/trunk/clio/clio/proxy.hpp clio/trunk/clio/clio/std_container.hpp clio/trunk/clio/tests/reference.test/output.txt clio/trunk/clio/tests/reference.test/reference.test.io clio/trunk/clio/tests/speed.test/output.txt clio/trunk/clio/tests/speed.test/speed.test.io Property Changed: ---------------- clio/trunk/clio/ Property changes on: clio/trunk/clio ___________________________________________________________________ Name: bzr:revision-info - timestamp: 2008-02-25 19:56:44.677999973 +0100 committer: Manuel Moos <z-...@us...> properties: branch-nick: src + timestamp: 2008-02-26 00:17:13.911000013 +0100 committer: Manuel Moos <z-...@us...> properties: branch-nick: clio 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 33 z-...@us...-20080224161454-lyyn0grllfn5qx8w 34 z-...@us...-20080224180639-fr6dqfch7kboocs0 35 z-...@us...-20080224181843-8iq9zyjoz4dprm8b 36 z-...@us...-20080224224147-cmxp11hux8yn3jbp 37 z-...@us...-20080224224848-0h65c9bpg637lgar 38 z-...@us...-20080224225219-0arhdm8hw42hptrf 39 z-...@us...-20080225000421-fh9p1qmu32awa41y 40 z-...@us...-20080225000607-bsvlilqbv5ssltr3 41 z-...@us...-20080225003311-fnfdbdvp3p2bw8b4 42 z-...@us...-20080225013618-jrkbe6q8gpdzbj3n 43 z-...@us...-20080225015144-8j759e33zdztmena 44 z-...@us...-20080225022114-1360a7t61rtei61d 45 z-...@us...-20080225023750-vf22upkbeiyoclbc 46 z-...@us...-20080225024308-j2a0nomtfuzfbjf8 47 z-...@us...-20080225100512-ck04wcqo0w3jibyq 48 z-...@us...-20080225103727-f42008yfu3y6q5r5 49 z-...@us...-20080225113757-opine59p0ak9r6h0 50 z-...@us...-20080225115932-akfi8jo7apw0phkk 51 z-...@us...-20080225120844-31fhi28emjcs4ys6 52 z-...@us...-20080225122224-wrmmr1nt5w9106rg 53 z-...@us...-20080225123606-ts2l2h3aivk9pplp 54 z-...@us...-20080225145431-x956npu0w5htu7sa 55 z-...@us...-20080225152517-hejvwwjukez9aemh 56 z-...@us...-20080225154230-rpq3t8xnbu99mx4t 57 z-...@us...-20080225162001-ukwye8clhep133jz 58 z-...@us...-20080225162148-mvmfjwz461o7xvaa 59 z-...@us...-20080225164010-oej2am8f8ysxnu3n 60 z-...@us...-20080225175844-w74is4pxw6zefuou 61 z-...@us...-20080225185644-df7z71i5bh7056tw + 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 34 z-...@us...-20080224180639-fr6dqfch7kboocs0 35 z-...@us...-20080224181843-8iq9zyjoz4dprm8b 36 z-...@us...-20080224224147-cmxp11hux8yn3jbp 37 z-...@us...-20080224224848-0h65c9bpg637lgar 38 z-...@us...-20080224225219-0arhdm8hw42hptrf 39 z-...@us...-20080225000421-fh9p1qmu32awa41y 40 z-...@us...-20080225000607-bsvlilqbv5ssltr3 41 z-...@us...-20080225003311-fnfdbdvp3p2bw8b4 42 z-...@us...-20080225013618-jrkbe6q8gpdzbj3n 43 z-...@us...-20080225015144-8j759e33zdztmena 44 z-...@us...-20080225022114-1360a7t61rtei61d 45 z-...@us...-20080225023750-vf22upkbeiyoclbc 46 z-...@us...-20080225024308-j2a0nomtfuzfbjf8 47 z-...@us...-20080225100512-ck04wcqo0w3jibyq 48 z-...@us...-20080225103727-f42008yfu3y6q5r5 49 z-...@us...-20080225113757-opine59p0ak9r6h0 50 z-...@us...-20080225115932-akfi8jo7apw0phkk 51 z-...@us...-20080225120844-31fhi28emjcs4ys6 52 z-...@us...-20080225122224-wrmmr1nt5w9106rg 53 z-...@us...-20080225123606-ts2l2h3aivk9pplp 54 z-...@us...-20080225145431-x956npu0w5htu7sa 55 z-...@us...-20080225152517-hejvwwjukez9aemh 56 z-...@us...-20080225154230-rpq3t8xnbu99mx4t 57 z-...@us...-20080225162001-ukwye8clhep133jz 58 z-...@us...-20080225162148-mvmfjwz461o7xvaa 59 z-...@us...-20080225164010-oej2am8f8ysxnu3n 60 z-...@us...-20080225175844-w74is4pxw6zefuou 61 z-...@us...-20080225185644-df7z71i5bh7056tw 62 z-...@us...-20080225231713-lk9zjwf6tlmck94z Modified: clio/trunk/clio/clio/primitiveproxy.hpp =================================================================== --- clio/trunk/clio/clio/primitiveproxy.hpp 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/clio/primitiveproxy.hpp 2008-02-26 01:03:10 UTC (rev 8125) @@ -112,6 +112,9 @@ CLIO_METHOD( clone ).TransferOwnership(); CLIO_INJECTCODE( clio::primitiveProxyCode ); + + typedef typename CLASS::REBOXER REBOXER; + REBOXER::template Reboxer< CLASS >::Register(); } CLIO_TEMPLATE_CLASS( clio::PrimitiveProxy, (1,(class))) @@ -122,6 +125,9 @@ CLIO_METHOD( clone ).TransferOwnership(); CLIO_INJECTCODE( clio::primitiveProxyCode ); + + typedef typename CLASS::REBOXER REBOXER; + REBOXER::template Reboxer< CLASS >::Register(); } CLIO_TEMPLATE_CLASS_SET_DEFAULTCONSTRUCTOR( clio::PrimitiveWrapper, (1,(class)), true ); Modified: clio/trunk/clio/clio/proxy.hpp =================================================================== --- clio/trunk/clio/clio/proxy.hpp 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/clio/proxy.hpp 2008-02-26 01:03:10 UTC (rev 8125) @@ -5,6 +5,7 @@ #include "classname.hpp" #include "dataconversion.hpp" #include "gcpointer.hpp" +#include "error.hpp" #include <sstream> #include <iostream> @@ -38,7 +39,7 @@ assert( proxy->GetObjectWrapper() &&proxy->GetObjectWrapper()->GetSelf() ); IoState * state = IoObject_state( proxy->GetObjectWrapper()->GetSelf() ); - IoObject * targetObject = ClassInfo< TARGET_PROXY >::Get().FetchIoObject( state ); + IoObject * targetObject = ClassInfo< TARGET_PROXY >::Get().FetchIoObject( target ); // have it retained IoState_stackRetain_( state, targetObject ); @@ -53,51 +54,210 @@ } }; -// class just to indicate that something is managed by proxy -class DataConverterProxyBase{}; - -template< class PROXY > -struct UnboxCasterRegistrator +// class bringing a proxy wrapping WRAPPED and one wrapping WRAPPED * together +// to provide a conversion operator +template< class WRAPPED > +class UnboxCasterManager { - typedef typename PROXY::ORIGINAL ORIGINAL; - typedef dataconversion::DataConverterManager< ORIGINAL > MANAGER; +public: + // the first step of the conversion: from the wrapper to the wrapped object + class IUnboxer + { + public: + virtual ~IUnboxer(){} - // do nothing if data conversion manager is not a proxy manager - static void Register( void * ) + // the class info of the source object + virtual IClassInfo & Class() const = 0; + + // extract the wrapped pointer. object points to a class managed by the given class info. + virtual WRAPPED * Get( void * object ) const = 0; + }; + + // the second step of the conversion: rewrap the pointer + class IReboxer { - } + public: + virtual ~IReboxer(){} - // further distinction between const and non-const values - static void Register( BoolToType< true > const & ) + // the class info of the destination object + virtual IClassInfo & Class() const = 0; + + // extract the wrapped pointer. Return value must point to an raw object managed by the class. + virtual void * Wrap( WRAPPED * toWrap ) const = 0; + }; + + // implementations of the interfaces + template< class WRAPPER > + class Unboxer: public IUnboxer { - typedef typename MANAGER::PROXY_CONST ORIGINAL_PROXY; + public: + // the class info of the source object + virtual IClassInfo & Class() const + { + return ClassInfo< WRAPPER >::Get(); + } - static UnboxCaster< PROXY, ORIGINAL_PROXY > caster; - ClassInfo< PROXY >::Get().RegisterBaseClass( ClassInfo< ORIGINAL_PROXY >::Get(), &caster ); - } + // extract the wrapped pointer. object points to a class managed by the given class info. + virtual WRAPPED * Get( void * object ) const + { + if ( !object ) + { + return NULL; + } + WRAPPER * wrapper = static_cast< WRAPPER * >( object ); + return TransformReference< WRAPPED * >::Transform( wrapper->Get() ); + } - static void Register( BoolToType< false > const & ) + static void Register() + { + static Unboxer unboxer; + UnboxCasterManager::RegisterUnboxer( unboxer ); + } + }; + + // the second step of the conversion: rewrap the pointer + template< class WRAPPER > + class Reboxer: public IReboxer { - typedef typename MANAGER::PROXY ORIGINAL_PROXY; + public: + // the class info of the destination object + virtual IClassInfo & Class() const + { + return ClassInfo< WRAPPER >::Get(); + } - static UnboxCaster< PROXY, ORIGINAL_PROXY > caster; - ClassInfo< PROXY >::Get().RegisterBaseClass( ClassInfo< ORIGINAL_PROXY >::Get(), &caster ); + // extract the wrapped pointer. Return value must point to an raw object managed by the class. + virtual void * Wrap( WRAPPED * toWrap ) const + { + return new WRAPPER( toWrap ); + } + + static void Register() + { + static Reboxer reboxer; + UnboxCasterManager::RegisterReboxer( reboxer ); + } + }; + + static void RegisterUnboxer( IUnboxer & unboxer ) + { + if ( unboxer_ ) + { +#ifndef NDEBUG + BreakPoint(); +#endif + return; + } + unboxer_ = & unboxer; + if ( reboxer_ ) + { + Finish(); + } } - static void Register( DataConverterProxyBase * ) + static void RegisterReboxer( IReboxer & reboxer ) { - typedef typename MANAGER::TArg TArg; - typedef typename ReoveIndirection< TArg >::Direct Direct; - Register( BoolToType< TestConst< Direct >::IsConst >() ); + if ( reboxer_ ) + { +#ifndef NDEBUG + BreakPoint(); +#endif + return; + } + reboxer_ = & reboxer; + if ( unboxer_ ) + { + Finish(); + } } +private: + class Caster: public ICaster + { + public: + Caster( IUnboxer & unboxer, IReboxer & reboxer ) + : ICaster( &unboxer.Class(), &reboxer.Class() ) + , unboxer_( unboxer ) + , reboxer_( reboxer ) + {} + private: + virtual void * DoCast ( void * source ) const CLIO_NOTHROW + { + // unbox + WRAPPED * wrapped = unboxer_.Get( source ); - static void Register() + // rebox + void * rewrap = reboxer_.Wrap( wrapped ); + + // but wait! We need to make sure the rewrapper is retained. + IoObject * targetObject = reboxer_.Class().FetchIoObject( rewrap ); + IoState_stackRetain_( IoObject_state( targetObject ), targetObject ); + + return rewrap; + } + + virtual void * DoCastBack ( void * source ) const CLIO_NOTHROW + { + return NULL; + } + + IUnboxer & unboxer_; + IReboxer & reboxer_; + }; + + static void Finish() { - // call the right function - Register( static_cast< MANAGER * >(NULL) ); + // create caster and register it + static Caster caster( *unboxer_, *reboxer_ ); + unboxer_->Class().RegisterBaseClass( reboxer_->Class(), &caster ); } + + static IUnboxer * unboxer_; + static IReboxer * reboxer_; }; +template< class WRAPPED > +typename UnboxCasterManager< WRAPPED >::IUnboxer * UnboxCasterManager< WRAPPED >::unboxer_ = 0; +template< class WRAPPED > +typename UnboxCasterManager< WRAPPED >::IReboxer * UnboxCasterManager< WRAPPED >::reboxer_ = 0; + +// overloads of the unboxer for references and pointers +template< class WRAPPER, class WRAPPED > +class Unboxer +{ +public: + static void Register(){} +}; + + +// overloads of the unboxer for references and pointers +template< class WRAPPER, class WRAPPED > +class Unboxer< WRAPPER, WRAPPED & >: public UnboxCasterManager< WRAPPED >::template Unboxer< WRAPPER > +{}; + +// overloads of the unboxer for references and pointers +template< class WRAPPER, class WRAPPED > +class Unboxer< WRAPPER, WRAPPED * >: public UnboxCasterManager< WRAPPED >::template Unboxer< WRAPPER > +{}; + +// real reboxer +struct RealReboxer +{ + template< class WRAPPER > + class Reboxer: public UnboxCasterManager< typename WRAPPER::ORIGINAL >::template Reboxer < WRAPPER > + {}; +}; + +// reboxer, fake version (we don't want wrappers to act as reboxers, that would defeat the purpose) +struct FakeReboxer +{ + template< class WRAPPER > + class Reboxer + { + public: + static void Register(){} + }; +}; + // Wrapper objects. T should be the raw type of the wrapped object without const. template< class T > class ProxyConst: public IChained @@ -164,6 +324,9 @@ public: typedef Proxy< ORIGINAL const > CONST; + // this class is really good for reboxing + typedef RealReboxer REBOXER; + // creates proxy for original explicit Proxy( ORIGINAL * original ) : original_( original ) @@ -256,6 +419,9 @@ class Wrapper: public ProxyBase< typename TestConst< ORIGINAL >::NoConst > { public: + // this class is not good for reboxing + typedef FakeReboxer REBOXER; + // creates proxy for original explicit Wrapper( ORIGINAL & original ) : wrapped_( original ) @@ -338,7 +504,7 @@ // and is supposed to be derived from IChained. Not surprisingly, Wrapper<> and Proxy<> // apply :) -template< class ORIGINAL, class PROXY_ > class DataConverterProxy: public DataConverterDefs< ORIGINAL >, public DataConverterProxyBase +template< class ORIGINAL, class PROXY_ > class DataConverterProxy: public DataConverterDefs< ORIGINAL > { public: typedef PROXY_ PROXY; // proxy itself @@ -495,18 +661,20 @@ CLIO_TEMPLATE_CLASS_SET_ABSTRACT( clio::ProxyConst, (1,(class)), true ); CLIO_TEMPLATE_CLASS( clio::ProxyConst, (1,(class)) ) { - UnboxCasterRegistrator< CLASS >::Register(); typedef typename CLASS::BASE BASE; CLIO_CLASS_BASE( BASE ); + + Unboxer< CLASS, T1 const >::Register(); } CLIO_TEMPLATE_CLASS_SET_DEFAULTCONSTRUCTOR( clio::ProxyNonConst, (1,(class)), false ); CLIO_TEMPLATE_CLASS_SET_ABSTRACT( clio::ProxyNonConst, (1,(class)), true ); CLIO_TEMPLATE_CLASS( clio::ProxyNonConst, (1,(class)) ) { - UnboxCasterRegistrator< CLASS >::Register(); typedef typename CLASS::BASE BASE; CLIO_CLASS_BASE( BASE ); + + Unboxer< CLASS, T1 >::Register(); } CLIO_TEMPLATE_CLASS( clio::ProxyBase, (1,(class)) ) Modified: clio/trunk/clio/clio/std_container.hpp =================================================================== --- clio/trunk/clio/clio/std_container.hpp 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/clio/std_container.hpp 2008-02-26 01:03:10 UTC (rev 8125) @@ -117,6 +117,9 @@ CLIO_METHOD( clone ).TransferOwnership(); CLIO_INJECTCODE( vectorProxyCodeConst ); + + typedef typename CLASS::REBOXER REBOXER; + REBOXER::template Reboxer< CLASS >::Register(); } CLIO_TEMPLATE_CLASS( clio::VectorProxy, (1,(class))) @@ -128,6 +131,9 @@ CLIO_METHOD( pop ); CLIO_INJECTCODE( vectorProxyCode ); + + typedef typename CLASS::REBOXER REBOXER; + REBOXER::template Reboxer< CLASS >::Register(); } CLIO_TEMPLATE_CLASS_EX( std::vector, (1,(class)), "RawVector" ){} Modified: clio/trunk/clio/tests/reference.test/output.txt =================================================================== --- clio/trunk/clio/tests/reference.test/output.txt 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/tests/reference.test/output.txt 2008-02-26 01:03:10 UTC (rev 8125) @@ -1,4 +1,3 @@ - <<<< y := ReturnTest nop("bla") <<<< writeln(y .. y) blabla @@ -27,3 +26,13 @@ <<<< writeln("z =", x) z =bla <<<< z set("bla") + +<<<< rt := ReturnTest clone +<<<< rt get set( "blubb" ) +<<<< pp := rt getpp +<<<< pp type println +Clio Ref With(Clio String) [clio::ConstPrimitiveProxy<clio::Proxy<string *>>] +<<<< pp set( "ble" ) +<<<< ReturnTest nop(pp) println +ble + Modified: clio/trunk/clio/tests/reference.test/reference.test.io =================================================================== --- clio/trunk/clio/tests/reference.test/reference.test.io 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/tests/reference.test/reference.test.io 2008-02-26 01:03:10 UTC (rev 8125) @@ -1,13 +1,3 @@ -pp := ReturnTest clone getpp -ReturnTest nop(pp) - -pp type println -pp get type println -pp get get type println -Clio Ref With(Clio String) type println -ReturnTest nop(pp get) - - y := ReturnTest nop("bla") writeln(y .. y) x := ReturnTest clone get @@ -25,3 +15,10 @@ writeln("x =", x) writeln("z =", x) z set("bla") + +rt := ReturnTest clone +rt get set( "blubb" ) +pp := rt getpp +pp type println +pp set( "ble" ) +ReturnTest nop(pp) println Modified: clio/trunk/clio/tests/speed.test/output.txt =================================================================== --- clio/trunk/clio/tests/speed.test/output.txt 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/tests/speed.test/output.txt 2008-02-26 01:03:10 UTC (rev 8125) @@ -19,7 +19,7 @@ <<<< time_clio := timestamp_clio - start <<<< time_io := timestamp_io - timestamp_clio -<<<< if( time_clio > 2 * time_io, writeln( "Clio is slow! Time clio: ", time_clio, " Time Io: ", time_io ), writeln("Fast enough.") ) +<<<< if( time_clio > 5 * time_io, writeln( "Clio is slow! Time clio: ", time_clio, " Time Io: ", time_io ), writeln("Fast enough.") ) Fast enough. Modified: clio/trunk/clio/tests/speed.test/speed.test.io =================================================================== --- clio/trunk/clio/tests/speed.test/speed.test.io 2008-02-25 19:01:38 UTC (rev 8124) +++ clio/trunk/clio/tests/speed.test/speed.test.io 2008-02-26 01:03:10 UTC (rev 8125) @@ -19,5 +19,5 @@ time_clio := timestamp_clio - start time_io := timestamp_io - timestamp_clio -if( time_clio > 2 * time_io, writeln( "Clio is slow! Time clio: ", time_clio, " Time Io: ", time_io ), writeln("Fast enough.") ) +if( time_clio > 5 * time_io, writeln( "Clio is slow! Time clio: ", time_clio, " Time Io: ", time_io ), writeln("Fast enough.") ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |