00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #ifndef IH_SENF_Socket_SocketPolicy_
00028 #define IH_SENF_Socket_SocketPolicy_ 1
00029
00030
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>
00052
00053 #include <senf/Utils/mpl.hh>
00054 #include <senf/Utils/pool_alloc_mixin.hh>
00055
00056
00057
00059
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 }
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
00256
00257
00258
00259
00260
00261
00262
00263