4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 // Stefan Bund <stefan.bund@fokus.fraunhofer.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.
23 #ifndef IH_SocketPolicy_
24 #define IH_SocketPolicy_ 1
27 #include <boost/preprocessor/seq/for_each.hpp>
28 #include <boost/preprocessor/seq/for_each_i.hpp>
29 #include <boost/preprocessor/seq/size.hpp>
30 #include <boost/preprocessor/seq/pop_front.hpp>
31 #include <boost/preprocessor/punctuation/comma_if.hpp>
32 #include <boost/preprocessor/repetition/enum_params.hpp>
33 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
34 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
35 #include <boost/preprocessor/cat.hpp>
36 #include <boost/preprocessor/seq/elem.hpp>
37 #include <boost/preprocessor/arithmetic/dec.hpp>
38 #include <boost/preprocessor/iteration/local.hpp>
39 #include <boost/preprocessor/control/if.hpp>
40 #include <boost/preprocessor/comparison/equal.hpp>
42 #include <boost/type_traits.hpp>
43 #include <boost/mpl/vector.hpp>
44 #include <boost/mpl/fold.hpp>
45 #include <boost/mpl/if.hpp>
46 #include <boost/mpl/and.hpp>
47 #include <boost/utility.hpp> // for enable_if
49 ///////////////////////////////ih.p////////////////////////////////////////
54 # define SATLIB_SOCKET_POLICIES_N BOOST_PP_SEQ_SIZE( SATLIB_SOCKET_POLICIES )
56 // This REALLY is bad ... but we just need an Address member in
57 // AddressingPolicyBase as long as ClientSocketHandle /
58 // ServerSocketHandle don't make use of enable_if for each and
59 // every member they define ...
61 struct AddressingPolicyBase
63 virtual ~ AddressingPolicyBase() {}
72 # define SP_DeclareBase(x1,x2,SomePolicy) \
73 struct BOOST_PP_CAT(SomePolicy,Base) \
74 { virtual ~ BOOST_PP_CAT(SomePolicy,Base) () {} }; \
75 typedef BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(Unspecified,SomePolicy);
77 BOOST_PP_SEQ_FOR_EACH( SP_DeclareBase, , BOOST_PP_SEQ_POP_FRONT( SATLIB_SOCKET_POLICIES ) )
79 # undef SP_DeclareBase
81 struct SocketPolicyBase
83 virtual ~SocketPolicyBase() {}
85 # define SP_DeclareTypedef(x1,x2,SomePolicy) \
86 typedef BOOST_PP_CAT(SomePolicy,Base) SomePolicy; \
87 BOOST_PP_CAT(SomePolicy,Base) BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \
88 virtual BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
89 { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
91 BOOST_PP_SEQ_FOR_EACH( SP_DeclareTypedef, , SATLIB_SOCKET_POLICIES )
93 # undef SP_DeclareTypedef
96 # define SP_TemplateArgs(x1,x2,n,SomePolicy) \
97 BOOST_PP_COMMA_IF( n ) \
98 class BOOST_PP_CAT(SomePolicy,_) = BOOST_PP_CAT(SomePolicy,Base)
100 template < BOOST_PP_SEQ_FOR_EACH_I( SP_TemplateArgs, , SATLIB_SOCKET_POLICIES ) >
102 : public SocketPolicyBase
104 # define SP_DeclarePolicyMember(x1,x2,SomePolicy) \
105 typedef BOOST_PP_CAT(SomePolicy,_) SomePolicy; \
106 SomePolicy BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); \
107 BOOST_PP_CAT(SomePolicy,Base) const & BOOST_PP_CAT(the,SomePolicy) () const \
108 { return BOOST_PP_CAT(BOOST_PP_CAT(the,SomePolicy),_); }
110 BOOST_PP_SEQ_FOR_EACH( SP_DeclarePolicyMember, , SATLIB_SOCKET_POLICIES )
111 # undef SP_DeclarePolicyMember
113 static void checkBaseOf(SocketPolicyBase const & other);
116 # undef SP_TemplateArgs
123 struct SocketPolicy_rv
126 template <class Base, class Policy, int N>
127 struct MakeSocketPolicy_merge
130 # define SP_DeclareMakeSocketPolicy_merge_member(r,n,m,SomePolicy) \
131 BOOST_PP_COMMA_IF( m ) \
132 BOOST_PP_IIF( BOOST_PP_EQUAL(n,m), Policy, typename Base::SomePolicy )
134 # define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC( SATLIB_SOCKET_POLICIES_N ) )
135 # define BOOST_PP_LOCAL_MACRO(n) \
136 SocketPolicy_rv<n> MakeSocketPolicy_merge_(BOOST_PP_CAT( BOOST_PP_SEQ_ELEM( n, SATLIB_SOCKET_POLICIES ),Base)*); \
138 template <class Base, class Policy> \
139 struct MakeSocketPolicy_merge<Base,Policy,sizeof(SocketPolicy_rv<n>)> \
141 typedef SocketPolicy< \
142 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareMakeSocketPolicy_merge_member, n, SATLIB_SOCKET_POLICIES ) \
146 # include BOOST_PP_LOCAL_ITERATE()
148 # undef SP_DeclareMakeSocketPolicy_merge_member
150 struct MakeSocketPolicy_fold
152 template <class Base, class Policy>
154 : MakeSocketPolicy_merge<Base,
156 sizeof(MakeSocketPolicy_merge_(static_cast<Policy*>(0)))>
159 template <class Base>
160 struct apply<Base,nil>
166 template <class Base, class Vector>
167 struct MakeSocketPolicy_impl
169 typedef typename boost::mpl::fold< Vector, Base, MakeSocketPolicy_fold >::type policy;
172 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
173 BOOST_PP_COMMA_IF( n ) \
174 typename Base::SomePolicy *
176 template <class Base>
177 SocketPolicy_rv<1> SocketPolicy_checkcompat_(
178 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) );
180 # undef SP_DeclareArguments
182 template <class Base>
183 SocketPolicy_rv<2> SocketPolicy_checkcompat_(
184 BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, void * BOOST_PP_INTERCEPT ) );
187 struct SocketPolicy_checkcompat
188 : public boost::false_type
192 struct SocketPolicy_checkcompat<sizeof(SocketPolicy_rv<1>)>
193 : public boost::true_type
197 # define SP_DeclareArguments(x1,x2,n,SomePolicy) \
198 BOOST_PP_COMMA_IF( n ) \
199 static_cast<typename Derived::SomePolicy *>(0)
201 template <class Base, class Derived>
202 struct SocketPolicy_compatibility
203 : public SocketPolicy_checkcompat< sizeof(
204 SocketPolicy_checkcompat_<Base>(
205 BOOST_PP_SEQ_FOR_EACH_I( SP_DeclareArguments, , SATLIB_SOCKET_POLICIES ) )) >
210 template < BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( SATLIB_SOCKET_POLICIES_N, class T, satcom::lib::impl::nil ) >
211 class MakeSocketPolicy
212 : public boost::mpl::if_< boost::is_convertible< T0*, SocketPolicyBase* >,
213 impl::MakeSocketPolicy_impl< T0, boost::mpl::vector< BOOST_PP_ENUM_SHIFTED_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > >,
214 impl::MakeSocketPolicy_impl< SocketPolicy<>,
215 boost::mpl::vector< BOOST_PP_ENUM_PARAMS( SATLIB_SOCKET_POLICIES_N, T ) > > >::type
218 template <class BasePolicy, class DerivedPolicy>
219 struct SocketPolicyIsBaseOf
220 : public boost::mpl::if_< boost::mpl::and_< boost::is_convertible< BasePolicy*, SocketPolicyBase* >,
221 boost::is_convertible< DerivedPolicy*, SocketPolicyBase* > >,
222 impl::SocketPolicy_compatibility<BasePolicy,DerivedPolicy>,
223 boost::false_type >::type
226 # define SP_DefineConditions(x1,x2,SomePolicy) \
227 template <class Policy, class Trait> \
228 struct BOOST_PP_CAT(SomePolicy,Is) \
229 : public boost::is_convertible< typename Policy::SomePolicy*, Trait* > \
232 template <class Policy, class Trait> \
233 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),Is) \
234 : public boost::enable_if< BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait> > \
237 template <class Policy, class Trait> \
238 struct BOOST_PP_CAT(BOOST_PP_CAT(If,SomePolicy),IsNot) \
239 : public boost::enable_if_c< ! BOOST_PP_CAT(SomePolicy,Is)<Policy,Trait>::value > \
242 BOOST_PP_SEQ_FOR_EACH( SP_DefineConditions, , SATLIB_SOCKET_POLICIES )
244 # undef SP_DefineConditions
248 ///////////////////////////////ih.e////////////////////////////////////////
254 // c-file-style: "satcom"