From 45508d07e1c407d1148ce7340c55f2a28a3a3368 Mon Sep 17 00:00:00 2001 From: Gerd v. Egidy Date: Wed, 23 Jul 2008 14:20:30 +0000 Subject: [PATCH] libt2n: (gerd) some progress with T2nWrapper (compiles but not complete yet) --- src/client_wrapper.hxx | 212 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 212 insertions(+), 0 deletions(-) create mode 100644 src/client_wrapper.hxx diff --git a/src/client_wrapper.hxx b/src/client_wrapper.hxx new file mode 100644 index 0000000..08cd397 --- /dev/null +++ b/src/client_wrapper.hxx @@ -0,0 +1,212 @@ +/*************************************************************************** + * Copyright (C) 2008 by Gerd v. Egidy and Reinhard Pfau * + * gve@intra2net.com * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef __LIBT2N_CLIENT_WRAPPER +#define __LIBT2N_CLIENT_WRAPPER + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#ifndef T2NWRAPPER_MAX_ARGS +#define T2NWRAPPER_MAX_ARGS 9 +#endif + +namespace libt2n +{ + +class ConnectionInitData +{ + public: + + virtual std::auto_ptr createConnection()=0; + + virtual ~ConnectionInitData() + { } +}; + +class TrivialHandler +{ + public: + static void handle( boost::function< void() > f) + { + f(); + } +}; + +// contains the internal stuff needed for T2nWrapper +namespace detail +{ + + template< typename T > + struct TypeWrap + { + typedef T type; + }; + + template< > + struct TypeWrap< void > + { + typedef int type; + }; + + template< typename R > + struct Call + { + typedef boost::function< R() > FuncType; + + FuncType function; + R& result; + + Call( FuncType f, R& res ) : function(f), result( res ) {} + + void operator()() + { + result= function(); + } + }; + + template< > + struct Call + { + typedef boost::function< void() > FuncType; + typedef TypeWrap< void >::type ResultType; + + FuncType function; + ResultType& result; + + Call( FuncType f, ResultType& res ) : function(f), result( res ) {} + + void operator()() + { + function(); + result= ResultType(); + } + }; +} // eo namespace detail + +template< + class Client, + class Handler = TrivialHandler +> +class T2nWrapper +{ + private: + + std::auto_ptr conndConn; + std::auto_ptr client; + + static std::auto_ptr singletonObject; + static std::auto_ptr initData; + + // create a prep-method for each possible number of parameters +#define _GEN_ARG(z,n,d) Arg ## n arg ##n +#define _GEN_PREP(z,n,d) \ + template< typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,typename Arg) > \ + static boost::function< R(Client*) > prep \ + ( \ + R(Client::*f)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM( n, _GEN_ARG, ~ ) \ + ) \ + { \ + return boost::bind< R > \ + ( \ + f, _1 BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,arg) \ + ); \ + } // eo prep + + BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1) , _GEN_PREP, ~ ) + +#undef _GEN_PREP +#undef _GEN_ARG + + static void ensureSingletonThere(void) + { + if (singletonObject.get() == NULL) + { + // we need to initialize + + if (initData.get() == NULL) + throw std::logic_error("T2nWrapper singleton used before setting initData"); + + std::auto_ptr myConndConn=initData->createConnection(); + + } + } + + template< typename R > + static + typename detail::TypeWrap::type real_exec( boost::function< R(Client*) > f) + { + ensureSingletonThere(); + + typename detail::TypeWrap::type result; + detail::Call call( boost::bind( f, &(*(singletonObject->client))), result ); + Handler::handle( call ); + return result; + } + + public: + + static void setInitData(std::auto_ptr newInitData) + { initData=newInitData; } + static ConnectionInitData* getInitData(void) + { return initData.get(); } + + T2nWrapper() + { + client=std::auto_ptr(new Client(*conndConn)); + } + + // create an exec-method for each possible number of parameters +#define _GEN_PLACEHOLDER(z,n,d) BOOST_PP_CAT(_,BOOST_PP_ADD(n,1)) +#define _GEN_EXEC(z,n,d) \ + template< typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,typename Arg) > \ + static boost::function< R( BOOST_PP_ENUM_PARAMS(n,Arg) ) > exec \ + ( \ + R(Client::*f)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \ + ) \ + { \ + boost::function(*p)(R(Client::*)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \ + BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg)) \ + = &T2nWrapper::template prep; \ + return boost::bind \ + ( \ + T2nWrapper::template real_exec, \ + boost::bind( p, f BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n, _GEN_PLACEHOLDER, ~ ) ) \ + ); \ + } // eo exec + + BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1), _GEN_EXEC, ~ ) + +#undef _GEN_EXEC +#undef _GEN_PLACEHOLDER + +}; + +} +#endif -- 1.7.1