4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief Policy Framework internal header
32 #ifndef IH_SENF_Socket_SocketPolicy_
33 #define IH_SENF_Socket_SocketPolicy_ 1
36 #include <boost/preprocessor/seq/for_each.hpp>
37 #include <boost/preprocessor/seq/for_each_i.hpp>
38 #include <boost/preprocessor/seq/size.hpp>
39 #include <boost/preprocessor/seq/pop_front.hpp>
40 #include <boost/preprocessor/punctuation/comma_if.hpp>
41 #include <boost/preprocessor/repetition/enum_params.hpp>
42 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
43 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
44 #include <boost/preprocessor/cat.hpp>
45 #include <boost/preprocessor/seq/elem.hpp>
46 #include <boost/preprocessor/arithmetic/dec.hpp>
47 #include <boost/preprocessor/iteration/local.hpp>
48 #include <boost/preprocessor/control/if.hpp>
49 #include <boost/preprocessor/comparison/equal.hpp>
51 #include <boost/type_traits.hpp>
52 #include <boost/mpl/vector.hpp>
53 #include <boost/mpl/fold.hpp>
54 #include <boost/mpl/if.hpp>
55 #include <boost/mpl/and.hpp>
56 #include <boost/utility.hpp> // for enable_if
58 #include <senf/Utils/mpl.hh>
59 #include <senf/Utils/pool_alloc_mixin.hh>
61 //-/////////////////////////////////////////////////////////////////////////////////////////////////
64 // Hide this code from doxygen
68 # define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES )
70 # define SP_DeclareAlias(x1,x2,SomePolicy) \
71 typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
73 BOOST_PP_SEQ_FOR_EACH( SP_DeclareAlias, , SENF_SOCKET_POLICIES )
75 # undef SP_DeclareAlias
77 struct SocketPolicyBase
79 virtual ~SocketPolicyBase();
81 # define SP_Declare(x1,x2,SomePolicy) \
82 virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () \
85 BOOST_PP_SEQ_FOR_EACH( SP_Declare, , SENF_SOCKET_POLICIES )
90 # define SP_TemplateArgs(x1,x2,n,SomePolicy) \
91 BOOST_PP_COMMA_IF( n ) \
92 class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
93 # define SP_TemplateParms(x1,x2,n,SomePolicy) \
94 BOOST_PP_COMMA_IF( n ) BOOST_PP_CAT(SomePolicy,_)
96 template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) >
98 : public SocketPolicyBase,
99 public senf::pool_alloc_mixin<
100 SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParms, , SENF_SOCKET_POLICIES ) > >
102 # define SP_DeclarePolicyMember(x1,x2,SomePolicy) \
103 typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \
104 SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \
105 BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
106 { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
108 BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SENF_SOCKET_POLICIES )
109 # undef SP_DeclarePolicyMember
111 static void checkBaseOf(SocketPolicyBase const & other);
114 # undef SP_TemplateArgs
115 # undef SP_TemplateParms
119 template <class Base, class Policy, int _>
120 struct MakeSocketPolicy_merge
123 # define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \
124 BOOST_PP_COMMA_IF( m ) \
125 BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
127 # define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) )
128 # define BOOST_PP_LOCAL_MACRO(n) \
129 senf::mpl::rv<n> MakeSocketPolicy_merge_( \
130 BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \
132 template <class Base, class Policy> \
133 struct MakeSocketPolicy_merge<Base,Policy,n> \
135 typedef SocketPolicy< \
136 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, \
138 SENF_SOCKET_POLICIES ) \
142 # include BOOST_PP_LOCAL_ITERATE()
144 # undef SP_DeclareMakeSocketPolicy_merge_member
146 struct MakeSocketPolicy_fold
148 template <class Base, class Policy>
150 : MakeSocketPolicy_merge<Base,
152 SENF_MPL_RV(MakeSocketPolicy_merge_(static_cast<Policy*>(0)))>
155 template <class Base>
156 struct apply<Base,mpl::nil>
162 template <class Base, class Vector>
163 struct MakeSocketPolicy_impl
165 typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
168 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
169 BOOST_PP_COMMA_IF( n ) \
170 typename Base::SomePolicy *
172 template <class Base>
173 senf::mpl::rv<1> SocketPolicy_checkcompat_(
174 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) );
176 # undef SP_DeclareArguments
178 template <class Base>
179 senf::mpl::rv<2> SocketPolicy_checkcompat_( ... );
182 struct SocketPolicy_checkcompat
183 : public boost::false_type
187 struct SocketPolicy_checkcompat<1>
188 : public boost::true_type
192 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
193 BOOST_PP_COMMA_IF( n ) \
194 static_cast<typename Derived::SomePolicy *>(0)
196 template <class Base, class Derived>
197 struct SocketPolicy_compatibility
198 : public SocketPolicy_checkcompat< SENF_MPL_RV(
199 SocketPolicy_checkcompat_<Base>(
200 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) )) >
205 template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_SOCKET_POLICIES_N,
208 class MakeSocketPolicy
209 : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
210 impl::MakeSocketPolicy_impl<
213 BOOST_PP_ENUM_SHIFTED_PARAMS(
214 SENF_SOCKET_POLICIES_N, T ) > >,
215 impl::MakeSocketPolicy_impl<
218 BOOST_PP_ENUM_PARAMS(
219 SENF_SOCKET_POLICIES_N, T ) > > >::type
222 template <class BasePolicy, class DerivedPolicy>
223 struct SocketPolicyIsBaseOf
224 : public boost::mpl::if_<
225 boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >,
226 boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >,
227 impl::SocketPolicy_compatibility<BasePolicy,DerivedPolicy>,
232 # define SP_DefineConditions(x1,x2,SomePolicy) \
233 template <class Policy, class Trait> \
234 struct BOOST_PP_CAT(SomePolicy,Is) \
235 : public boost::is_convertible< typename Policy::SomePolicy*, Trait* > \
238 template <class Policy, class Trait> \
239 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is) \
240 : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> > \
243 template <class Policy, class Trait> \
244 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot) \
245 : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \
248 BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SENF_SOCKET_POLICIES )
250 # undef SP_DefineConditions
256 //-/////////////////////////////////////////////////////////////////////////////////////////////////
263 // c-file-style: "senf"
264 // indent-tabs-mode: nil
265 // ispell-local-dictionary: "american"
266 // compile-command: "scons -u test"
267 // comment-column: 40