Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Directories
  • File List
  • File Members

SocketPolicy.ih

Go to the documentation of this file.
00001 // $Id: SocketPolicy.ih 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2006
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00027 #ifndef IH_SENF_Socket_SocketPolicy_
00028 #define IH_SENF_Socket_SocketPolicy_ 1
00029 
00030 // Custom includes
00031 #include <boost/preprocessor/seq/for_each.hpp>
00032 #include <boost/preprocessor/seq/for_each_i.hpp>
00033 #include <boost/preprocessor/seq/size.hpp>
00034 #include <boost/preprocessor/seq/pop_front.hpp>
00035 #include <boost/preprocessor/punctuation/comma_if.hpp>
00036 #include <boost/preprocessor/repetition/enum_params.hpp>
00037 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
00038 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
00039 #include <boost/preprocessor/cat.hpp>
00040 #include <boost/preprocessor/seq/elem.hpp>
00041 #include <boost/preprocessor/arithmetic/dec.hpp>
00042 #include <boost/preprocessor/iteration/local.hpp>
00043 #include <boost/preprocessor/control/if.hpp>
00044 #include <boost/preprocessor/comparison/equal.hpp>
00045 
00046 #include <boost/type_traits.hpp>
00047 #include <boost/mpl/vector.hpp>
00048 #include <boost/mpl/fold.hpp>
00049 #include <boost/mpl/if.hpp>
00050 #include <boost/mpl/and.hpp>
00051 #include <boost/utility.hpp> // for enable_if
00052 
00053 #include <senf/Utils/mpl.hh>
00054 #include <senf/Utils/pool_alloc_mixin.hh>
00055 
00056 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00057 
00059 // Hide this code from doxygen
00060 
00061 namespace senf {
00062 
00063 #   define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES )
00064 
00065 #   define SP_DeclareAlias(x1,x2,SomePolicy)                                                      \
00066         typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
00067 
00068     BOOST_PP_SEQ_FOR_EACH( SP_DeclareAlias, , SENF_SOCKET_POLICIES )
00069 
00070 #   undef SP_DeclareAlias
00071 
00072     struct SocketPolicyBase
00073     {
00074         virtual ~SocketPolicyBase();
00075 
00076 #       define SP_Declare(x1,x2,SomePolicy)                                                       \
00077             virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) ()         \
00078                 const = 0;
00079 
00080         BOOST_PP_SEQ_FOR_EACH( SP_Declare, , SENF_SOCKET_POLICIES )
00081 
00082 #       undef SP_Declare
00083     };
00084 
00085 #   define SP_TemplateArgs(x1,x2,n,SomePolicy)                                                    \
00086         BOOST_PP_COMMA_IF( n )                                                                    \
00087         class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
00088 #   define SP_TemplateParms(x1,x2,n,SomePolicy)                                                   \
00089         BOOST_PP_COMMA_IF( n ) BOOST_PP_CAT(SomePolicy,_)
00090 
00091     template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) >
00092     struct SocketPolicy
00093         : public SocketPolicyBase,
00094           public senf::pool_alloc_mixin<
00095               SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParms, , SENF_SOCKET_POLICIES ) > >
00096     {
00097 #   define SP_DeclarePolicyMember(x1,x2,SomePolicy)                                               \
00098         typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy;                                            \
00099         SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_);                                  \
00100         BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const               \
00101             { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
00102 
00103         BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SENF_SOCKET_POLICIES )
00104 #   undef SP_DeclarePolicyMember
00105 
00106         static void checkBaseOf(SocketPolicyBase const & other);
00107     };
00108 
00109 #   undef SP_TemplateArgs
00110 #   undef SP_TemplateParms
00111 
00112 namespace impl {
00113 
00114     template <class Base, class Policy, int _>
00115     struct MakeSocketPolicy_merge
00116     {};
00117 
00118 #   define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy)                              \
00119         BOOST_PP_COMMA_IF( m )                                                                    \
00120         BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
00121 
00122 #    define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) )
00123 #    define BOOST_PP_LOCAL_MACRO(n)                                                               \
00124         senf::mpl::rv<n> MakeSocketPolicy_merge_(                                                 \
00125             BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*);                   \
00126                                                                                                   \
00127         template <class Base, class Policy>                                                       \
00128         struct MakeSocketPolicy_merge<Base,Policy,n>                                              \
00129         {                                                                                         \
00130             typedef SocketPolicy<                                                                 \
00131                BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member,                  \
00132                                         n,                                                        \
00133                                         SENF_SOCKET_POLICIES )                                    \
00134                > type;                                                                            \
00135         };
00136 
00137 #   include BOOST_PP_LOCAL_ITERATE()
00138 
00139 #   undef SP_DeclareMakeSocketPolicy_merge_member
00140 
00141     struct MakeSocketPolicy_fold
00142     {
00143         template <class Base, class Policy>
00144         struct apply
00145             : MakeSocketPolicy_merge<Base,
00146                                      Policy,
00147                                      SENF_MPL_RV(MakeSocketPolicy_merge_(static_cast<Policy*>(0)))>
00148         {};
00149 
00150         template <class Base>
00151         struct apply<Base,mpl::nil>
00152         {
00153             typedef Base type;
00154         };
00155     };
00156 
00157     template <class Base, class Vector>
00158     struct MakeSocketPolicy_impl
00159     {
00160         typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
00161     };
00162 
00163 #   define SP_DeclareArguments(x1,x2,n,SomePolicy)                                                \
00164         BOOST_PP_COMMA_IF( n )                                                                    \
00165         typename Base::SomePolicy *
00166 
00167     template <class Base>
00168     senf::mpl::rv<1> SocketPolicy_checkcompat_(
00169         BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) );
00170 
00171 #   undef SP_DeclareArguments
00172 
00173     template <class Base>
00174     senf::mpl::rv<2> SocketPolicy_checkcompat_( ... );
00175 
00176     template <int Size>
00177     struct SocketPolicy_checkcompat
00178         : public boost::false_type
00179     {};
00180 
00181     template<>
00182     struct SocketPolicy_checkcompat<1>
00183         : public boost::true_type
00184     {};
00185 
00186 
00187 #   define SP_DeclareArguments(x1,x2,n,SomePolicy)                                                \
00188         BOOST_PP_COMMA_IF( n )                                                                    \
00189         static_cast<typename Derived::SomePolicy *>(0)
00190 
00191     template <class Base, class Derived>
00192     struct SocketPolicy_compatibility
00193         : public SocketPolicy_checkcompat< SENF_MPL_RV(
00194             SocketPolicy_checkcompat_<Base>(
00195                 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) )) >
00196     {};
00197 
00198 } // namespace impl
00199 
00200     template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_SOCKET_POLICIES_N,
00201                                                     class T,
00202                                                     mpl::nil ) >
00203     class MakeSocketPolicy
00204         : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
00205                                   impl::MakeSocketPolicy_impl<
00206                                       T0,
00207                                       boost::mpl::vector<
00208                                           BOOST_PP_ENUM_SHIFTED_PARAMS(
00209                                               SENF_SOCKET_POLICIES_N, T ) > >,
00210                                   impl::MakeSocketPolicy_impl<
00211                                       SocketPolicy<>,
00212                                       boost::mpl::vector<
00213                                           BOOST_PP_ENUM_PARAMS(
00214                                               SENF_SOCKET_POLICIES_N, T ) > > >::type
00215     {};
00216 
00217     template <class BasePolicy, class DerivedPolicy>
00218     struct SocketPolicyIsBaseOf
00219         : public boost::mpl::if_<
00220               boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >,
00221                                 boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >,
00222               impl::SocketPolicy_compatibility<BasePolicy,DerivedPolicy>,
00223               boost::false_type
00224           >::type
00225     {};
00226 
00227 #   define SP_DefineConditions(x1,x2,SomePolicy)                                                  \
00228         template <class Policy, class Trait>                                                      \
00229         struct BOOST_PP_CAT(SomePolicy,Is)                                                        \
00230             : public boost::is_convertible< typename Policy::SomePolicy*, Trait* >                \
00231         {};                                                                                       \
00232                                                                                                   \
00233         template <class Policy, class Trait>                                                      \
00234         struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is)                                       \
00235             : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> >                \
00236         {};                                                                                       \
00237                                                                                                   \
00238         template <class Policy, class Trait>                                                      \
00239         struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot)                                    \
00240             : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value >     \
00241         {};
00242 
00243     BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SENF_SOCKET_POLICIES )
00244 
00245 #   undef SP_DefineConditions
00246 
00247 }
00248 
00250 
00251 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00252 #endif
00253 
00254 
00255 // Local Variables:
00256 // mode: c++
00257 // fill-column: 100
00258 // c-file-style: "senf"
00259 // indent-tabs-mode: nil
00260 // ispell-local-dictionary: "american"
00261 // compile-command: "scons -u test"
00262 // comment-column: 40
00263 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research