4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Policy Framework internal header
27 #ifndef IH_SENF_Socket_SocketPolicy_
28 #define IH_SENF_Socket_SocketPolicy_ 1
31 #include <boost/preprocessor/seq/for_each.hpp>
32 #include <boost/preprocessor/seq/for_each_i.hpp>
33 #include <boost/preprocessor/seq/size.hpp>
34 #include <boost/preprocessor/seq/pop_front.hpp>
35 #include <boost/preprocessor/punctuation/comma_if.hpp>
36 #include <boost/preprocessor/repetition/enum_params.hpp>
37 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
38 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
39 #include <boost/preprocessor/cat.hpp>
40 #include <boost/preprocessor/seq/elem.hpp>
41 #include <boost/preprocessor/arithmetic/dec.hpp>
42 #include <boost/preprocessor/iteration/local.hpp>
43 #include <boost/preprocessor/control/if.hpp>
44 #include <boost/preprocessor/comparison/equal.hpp>
46 #include <boost/type_traits.hpp>
47 #include <boost/mpl/vector.hpp>
48 #include <boost/mpl/fold.hpp>
49 #include <boost/mpl/if.hpp>
50 #include <boost/mpl/and.hpp>
51 #include <boost/utility.hpp> // for enable_if
53 #include "../Utils/mpl.hh"
54 #include "../Utils/pool_alloc_mixin.hh"
56 ///////////////////////////////ih.p////////////////////////////////////////
59 // Hide this code from doxygen
63 # define SENF_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SENF_SOCKET_POLICIES )
65 # define SP_DeclareAlias(x1,x2,SomePolicy) \
66 typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
68 BOOST_PP_SEQ_FOR_EACH( SP_DeclareAlias, , SENF_SOCKET_POLICIES )
70 # undef SP_DeclareAlias
72 struct SocketPolicyBase
74 virtual ~SocketPolicyBase();
76 # define SP_Declare(x1,x2,SomePolicy) \
77 virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () \
80 BOOST_PP_SEQ_FOR_EACH( SP_Declare, , SENF_SOCKET_POLICIES )
85 # define SP_TemplateArgs(x1,x2,n,SomePolicy) \
86 BOOST_PP_COMMA_IF( n ) \
87 class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
88 # define SP_TemplateParms(x1,x2,n,SomePolicy) \
89 BOOST_PP_COMMA_IF( n ) BOOST_PP_CAT(SomePolicy,_)
91 template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SENF_SOCKET_POLICIES ) >
93 : public SocketPolicyBase,
94 public senf::pool_alloc_mixin<
95 SocketPolicy< BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateParms, , SENF_SOCKET_POLICIES ) > >
97 # define SP_DeclarePolicyMember(x1,x2,SomePolicy) \
98 typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \
99 SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \
100 BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
101 { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
103 BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SENF_SOCKET_POLICIES )
104 # undef SP_DeclarePolicyMember
106 static void checkBaseOf(SocketPolicyBase const & other);
109 # undef SP_TemplateArgs
110 # undef SP_TemplateParms
114 template <class Base, class Policy, int _>
115 struct MakeSocketPolicy_merge
118 # define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \
119 BOOST_PP_COMMA_IF( m ) \
120 BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
122 # define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SENF_SOCKET_POLICIES_N ) )
123 # define BOOST_PP_LOCAL_MACRO(n) \
124 senf::mpl::rv<n> MakeSocketPolicy_merge_( \
125 BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SENF_SOCKET_POLICIES ),Base)*); \
127 template <class Base, class Policy> \
128 struct MakeSocketPolicy_merge<Base,Policy,n> \
130 typedef SocketPolicy< \
131 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, \
133 SENF_SOCKET_POLICIES ) \
137 # include BOOST_PP_LOCAL_ITERATE()
139 # undef SP_DeclareMakeSocketPolicy_merge_member
141 struct MakeSocketPolicy_fold
143 template <class Base, class Policy>
145 : MakeSocketPolicy_merge<Base,
147 SENF_MPL_RV(MakeSocketPolicy_merge_(static_cast<Policy*>(0)))>
150 template <class Base>
151 struct apply<Base,mpl::nil>
157 template <class Base, class Vector>
158 struct MakeSocketPolicy_impl
160 typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
163 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
164 BOOST_PP_COMMA_IF( n ) \
165 typename Base::SomePolicy *
167 template <class Base>
168 senf::mpl::rv<1> SocketPolicy_checkcompat_(
169 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) );
171 # undef SP_DeclareArguments
173 template <class Base>
174 senf::mpl::rv<2> SocketPolicy_checkcompat_( ... );
177 struct SocketPolicy_checkcompat
178 : public boost::false_type
182 struct SocketPolicy_checkcompat<1>
183 : public boost::true_type
187 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
188 BOOST_PP_COMMA_IF( n ) \
189 static_cast<typename Derived::SomePolicy *>(0)
191 template <class Base, class Derived>
192 struct SocketPolicy_compatibility
193 : public SocketPolicy_checkcompat< SENF_MPL_RV(
194 SocketPolicy_checkcompat_<Base>(
195 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SENF_SOCKET_POLICIES ) )) >
200 template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SENF_SOCKET_POLICIES_N,
203 class MakeSocketPolicy
204 : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
205 impl::MakeSocketPolicy_impl<
208 BOOST_PP_ENUM_SHIFTED_PARAMS(
209 SENF_SOCKET_POLICIES_N, T ) > >,
210 impl::MakeSocketPolicy_impl<
213 BOOST_PP_ENUM_PARAMS(
214 SENF_SOCKET_POLICIES_N, T ) > > >::type
217 template <class BasePolicy, class DerivedPolicy>
218 struct SocketPolicyIsBaseOf
219 : public boost::mpl::if_<
220 boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >,
221 boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >,
222 impl::SocketPolicy_compatibility<BasePolicy,DerivedPolicy>,
227 # define SP_DefineConditions(x1,x2,SomePolicy) \
228 template <class Policy, class Trait> \
229 struct BOOST_PP_CAT(SomePolicy,Is) \
230 : public boost::is_convertible< typename Policy::SomePolicy*, Trait* > \
233 template <class Policy, class Trait> \
234 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is) \
235 : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> > \
238 template <class Policy, class Trait> \
239 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot) \
240 : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \
243 BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SENF_SOCKET_POLICIES )
245 # undef SP_DefineConditions
251 ///////////////////////////////ih.e////////////////////////////////////////
258 // c-file-style: "senf"
259 // indent-tabs-mode: nil
260 // ispell-local-dictionary: "american"
261 // compile-command: "scons -u test"
262 // comment-column: 40