// $Id$ // // Copyright (C) 2006 // Fraunhofer Institute for Open Communication Systems (FOKUS) // // The contents of this file are subject to the Fraunhofer FOKUS Public License // Version 1.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // http://senf.berlios.de/license.html // // The Fraunhofer FOKUS Public License Version 1.0 is based on, // but modifies the Mozilla Public License Version 1.1. // See the full license text for the amendments. // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License // for the specific language governing rights and limitations under the License. // // The Original Code is Fraunhofer FOKUS code. // // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. // (registered association), Hansastraße 27 c, 80686 Munich, Germany. // All Rights Reserved. // // Contributor(s): // Stefan Bund /** \file \brief Policy Framework internal header */ #ifndef IH_SENF_Socket_SocketPolicy_ #define IH_SENF_Socket_SocketPolicy_ 1 // Custom includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // for enable_if #include #include //-///////////////////////////////////////////////////////////////////////////////////////////////// /// \cond disabled // Hide this code from doxygen namespace senf { # define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES ) # define SP_DeclareAlias(x1,x2,SomePolicy) \ typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy); BOOST_PP_SEQ_FOR_EACH( SP_DeclareAlias, , SENF_SOCKET_POLICIES ) # undef SP_DeclareAlias struct SocketPolicyBase { virtual ~SocketPolicyBase(); # define SP_Declare(x1,x2,SomePolicy) \ virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () \ const = 0; BOOST_PP_SEQ_FOR_EACH( SP_Declare, , SENF_SOCKET_POLICIES ) # undef SP_Declare }; # define SP_TemplateArgs(x1,x2,n,SomePolicy) \ BOOST_PP_COMMA_IF( n ) \ class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base) # define SP_TemplateParms(x1,x2,n,SomePolicy) \ BOOST_PP_COMMA_IF( n ) BOOST_PP_CAT(SomePolicy,_) template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) > struct SocketPolicy : public SocketPolicyBase, public senf::pool_alloc_mixin< SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParms, , SENF_SOCKET_POLICIES ) > > { # define SP_DeclarePolicyMember(x1,x2,SomePolicy) \ typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \ SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \ BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \ { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); } BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SENF_SOCKET_POLICIES ) # undef SP_DeclarePolicyMember static void checkBaseOf(SocketPolicyBase const & other); }; # undef SP_TemplateArgs # undef SP_TemplateParms namespace impl { template struct MakeSocketPolicy_merge {}; # define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \ BOOST_PP_COMMA_IF( m ) \ BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy ) # define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) ) # define BOOST_PP_LOCAL_MACRO(n) \ senf::mpl::rv MakeSocketPolicy_merge_( \ BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \ \ template \ struct MakeSocketPolicy_merge \ { \ typedef SocketPolicy< \ BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, \ n, \ SENF_SOCKET_POLICIES ) \ > type; \ }; # include BOOST_PP_LOCAL_ITERATE() # undef SP_DeclareMakeSocketPolicy_merge_member struct MakeSocketPolicy_fold { template struct apply : MakeSocketPolicy_merge(0)))> {}; template struct apply { typedef Base type; }; }; template struct MakeSocketPolicy_impl { typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy; }; # define SP_DeclareArguments(x1,x2,n,SomePolicy) \ BOOST_PP_COMMA_IF( n ) \ typename Base::SomePolicy * template senf::mpl::rv<1> SocketPolicy_checkcompat_( BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) ); # undef SP_DeclareArguments template senf::mpl::rv<2> SocketPolicy_checkcompat_( ... ); template struct SocketPolicy_checkcompat : public boost::false_type {}; template<> struct SocketPolicy_checkcompat<1> : public boost::true_type {}; # define SP_DeclareArguments(x1,x2,n,SomePolicy) \ BOOST_PP_COMMA_IF( n ) \ static_cast(0) template struct SocketPolicy_compatibility : public SocketPolicy_checkcompat< SENF_MPL_RV( SocketPolicy_checkcompat_( BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) )) > {}; } // namespace impl template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_SOCKET_POLICIES_N, class T, mpl::nil ) > class MakeSocketPolicy : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >, impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SENF_SOCKET_POLICIES_N, T ) > >, impl::MakeSocketPolicy_impl< SocketPolicy<>, boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SENF_SOCKET_POLICIES_N, T ) > > >::type {}; template struct SocketPolicyIsBaseOf : public boost::mpl::if_< boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >, boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >, impl::SocketPolicy_compatibility, boost::false_type >::type {}; # define SP_DefineConditions(x1,x2,SomePolicy) \ template \ struct BOOST_PP_CAT(SomePolicy,Is) \ : public boost::is_convertible< typename Policy::SomePolicy*, Trait* > \ {}; \ \ template \ struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is) \ : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is) > \ {}; \ \ template \ struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot) \ : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)::value > \ {}; BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SENF_SOCKET_POLICIES ) # undef SP_DefineConditions } /// \endcond //-///////////////////////////////////////////////////////////////////////////////////////////////// #endif // Local Variables: // mode: c++ // fill-column: 100 // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" // comment-column: 40 // End: