Move sourcecode into 'senf/' directory
[senf.git] / senf / Socket / SocketPolicy.hh
1 // $Id:SocketPolicy.hh 218 2007-03-20 14:39:32Z tho $
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief Policy Framework public header
25
26     \idea Creating a new Socket will create 3 new instances (The handle, the body, the policy) of
27         which 2 (argh) (body, policy) live on the heap. This is expensive. We should convert all the
28         policy classes to singletons and assign the same instance to all socket bodies with the same
29         policy. This would reduce the number of heap allocations per socket handle to one (which is
30         already optimized using the pool_alloc_mixin)
31  */
32
33 /** \defgroup policy_group The Policy Framework
34
35     <div class="diamap" name="SocketPolicy">
36     <span coords="39,229,182,257">\ref WritePolicyBase</span>
37     <span coords="17,76,210,105">\ref AddressingPolicyBase</span>
38     <span coords="29,114,194,143">\ref FramingPolicyBase</span>
39     <span coords="368,0,463,28">\ref PolicyBase</span>
40     <span coords="275,2,691,185">\ref SocketPolicy</span>
41     <span coords="0,152,227,181">\ref CommunicationPolicyBase</span>
42     <span coords="41,191,180,219">\ref ReadPolicyBase</span>
43     </div>
44     \htmlonly <img src="SocketPolicy.png" border="0" alt="SocketPolicy" usemap="#SocketPolicy"> \endhtmlonly
45
46     \section policy_group_introduction Introduction to the Policy Framework
47
48     The policy framework conceptually implements a list of parallel inheritance hierarchies each
49     covering a specific interface aspect of the socket handle. The socket handle itself only
50     provides minimal functionality. All further functionality is relayed to a policy class, or more
51     precisely, to a group of policy classes, one for each policy axis. The policy axis are
52
53     <dl><dt><em>addressingPolicy</em></dt><dd>configures, whether a socket is addressable and if
54     so, configures the address type</dd>
55
56     <dt><em>framingPolicy</em></dt> <dd>configures the type of framing the socket provides: either
57     no framing providing a simple i/o stream or packet framing</dd>
58
59     <dt><em>communicationPolicy</em></dt><dd>configures,if and how the communication partner is
60     selected</dd>
61
62     <dt><em>readPolicy</em></dt><dd>configures the readability of the socket</dd>
63
64     <dt><em>writePolicy</em></dt><dd>configures the writability of the socket</dd></dl>
65
66     The template senf::SocketPolicy combines these policy axis to form a concrete socket policy. In
67     a concrete policy, each of these policy axis is assigned a value, the policy value. This value
68     is identified by a class type, a policy class. E.g. possible values for <em>framingPolicy</em>
69     are <tt>DatagramFramingPolicy</tt> or <tt>StreamFramingPolicy</tt> which are classes derived
70     from the axis base class <tt>FramingPolicyBase</tt>. This base class also doubles as
71     <tt>UnspecifiedFramingPolicy</tt> (which is just a typedef alias).  If a policy axis is assigned
72     this Unspecified type, the axis is left unspecified, the concrete policy will be incomplete.
73
74     The senf::SocketPolicy template defines the behavior of a socket handle. The socket handle
75     instances do not implement any socket functionality themselves instead deferring the
76     implementation to the policy classes. The SocketHandle interface is therefore \e not implemented
77     using virtual members, all important socket functions can be inlined by the compiler to create
78     highly efficient code.
79
80     A senf::SocketPolicy instance can be incomplete. In this case it does \e not completely specify
81     the socket interface, it leaves some aspects open by assigning the Unspecified value to one or
82     more of the policy axis. A senf::SocketHandle based on such a policy will have a reduced
83     interface: It will only support those members for which the corresponding policies are defined.
84
85     To build a senf::SocketPolicy instance the senf::MakeSocketPolicy helper is provided. This
86     helper template takes any number (it is really limited to 6 Arguments but more arguments don't
87     make sense) of policy classes as it's argument. The MakeSocketPolicy helper will take the
88     arguments in the order they are specified and for each argument will check to which axis the
89     policy class belongs (by checking the base classes of that class) and assign it to the correct
90     policy axis in the senf::SocketPolicy template. If any policy axis are not specified, they are
91     defaulted to their corresponding Unspecified value. This helper frees you to specify the policy
92     classes in any order. An additional feature is, that you may specify a complete policy as a
93     first argument. This policy will then be used to provide default values for unspecified axis.
94
95     Two senf::SocketHandle's with different policies can be \e compatible. If they are, the more
96     specific SocketHandle can be converted (assigned to) the more basic SocketHandle. A SocketHandle
97     is more specific then another SocketHandle if the policy of the former is more specific then
98     that of the latter which means, that for each policy axis separately, the value of that axis of
99     the more specific policy is derived from or the same as the value of that axis in the more basic
100     policy. This is like converting a derived class pointer to a base class pointer, only it happens
101     separately but at the same time for each policy axis:
102
103     \code
104     // This defines an incomplete policy where addressingPolicy and writePolicy
105     // are unspecified
106     typedef senf::MakeSocketPolicy<
107         senf::StreamFramingPolicy,
108         senf::ConnectedCommunicationPolicy,
109         senf::ReadablePolicy
110         >::policy MyReadableSocketPolicy
111
112     typedef senf::ClientSocketHandle<MyReadableSocketPolicy> MyReadableHandle;
113
114     // TCPv4ClientSocketHandle is a socket handle with the policy equivalent to
115     // senf::MakeSocketPolicy<
116     //     INet4AddressingPolicy,
117     //     StreamFramingPolicy,
118     //     ConnectedCommunicationPolicy,
119     //     ReadablePolicy,
120     //     WritablePolicy>::policy
121     senf::TCPv4ClientSocketHandle tcpHandle (...);
122
123     MyReadableHandle myHandle (tcpHandle); // Conversion to more basic socket handle
124     \endcode
125
126     \section policy_group_details The Policy Framework Classes
127
128     In the following discussion, deeper insight into C++ and especially the concepts of template
129     meta-programming are needed. However, this information is only needed if you want to write new
130     policy classes or want to use the policy framework explicitly for your own involved
131     optimizations ... or if you are just plain curious :-)
132
133     In the following discussion we will use the following conventions:
134     \li \e Axis is one or \c AddressingPolicy, \c FramingPolicy, \c CommunicationPolicy, \c
135         ReadPolicy or \c WritePolicy
136     \li \e socketPolicy is any socket policy (that is, an instantiation of the SocketPolicy
137         template)
138     \li \e trait is an any policy class (that is, any class derived from one of the axis base
139         classes)
140
141     Each axis is comprised of a number of classes and templates (all in namespace senf of course):
142
143     <dl><dt>\e Axis \c Base (ex: AddressingPolicyBase)</dt><dd>Baseclass of all policies in this
144     axis</dd>
145
146     <dt>\c Unspecified \e Axis (ex: \ref UnspecifiedAddressingPolicy)</dt> <dd>An alias (typedef)
147     for \e Axis \c Base</dd>
148
149     <dt>\e Axis \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt> <dd>A template
150     metafunction returning \c boost::true_type, if \e trait (any class derived from \e Axis \c
151     Base) is a compatible policy value of the given \e socketPolicy</dd>
152
153     <dt>\c If \e Axis \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt> <dd>This
154     is a combination of \e Axis \c Is and \c boost::enable_if</dd>
155
156     <dt>\c If \e Axis \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
157     <dd>The inverse of above</dd> </dl>
158
159     These classes form the basis of the policy framework. To bind the policy axis together, there
160     are some more classes and templates.
161
162     <dl><dt>\c class \c SocketPolicyBase</dt> <dd>This class is the base class of the SocketPolicy
163     template. It is used to validate, that a class is really a SocketPolicy (by checking, that it
164     derives from SocketPolicyBase. This is simpler than checking the template directly).</dd>
165
166     <dt>\c template \c SocketPolicy < \e addressingPolicy, \e framingPolicy, \e communicationPolicy,
167     \e readPolicy, \e writePolicy ></dt> <dd>This is the central SocketPolicy
168     template. It combines a complete set of policy classes, one for each axis.</dd>
169
170     <dt>\c template \c MakeSocketPolicy < \e args ></dt> <dd>\c MakeSocketPolicy is a template
171     metafunction which simplifies building SocketPolicy instantiations. It takes any number (ok, up
172     to a maximum of 6) of policy classes as an argument (in any order). It will sort these arguments
173     into the SocketPolicy template arguments. If for some axis no class is specified, it's slot will
174     be filled with \c Unspecified \e Axis. Additionally, the first Argument may optionally be ab
175     arbitrary SocketPolicy. It will provide default values for unspecified axis</dd>
176
177     <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt> <dd>This template
178     metafunction will check, whether the socket policy \e derived is convertible to \e base. This
179     means, that for each axis, the corresponding policy class in \e derived must be derived or be
180     the same as the one on \e base.</dd> </dl>
181
182     \implementation All these classes are created automatically. The \c SENF_SOCKET_POLICIES macro
183     is a Boost.Preprocessor style sequence listing all policy axis. The Boost.Preprocessor library
184     is then used to generate the respective classes.
185
186     \section policy_implement Implementing Policy Classes
187
188     To define a new policy class, derive from the corresponding base class for your policy axes. The
189     only policy axis which might possibly need to be extended is the addressing policy
190     (AddressingPolicyBase). See the Documentation of these classes for more information on which
191     members can be implemented.
192
193     All members you define must be static. For any of the policy classes, you must only define those
194     members which are supported by your implementation. If you leave out a member you automatically
195     disable the corresponding functionality in the ClientSocketHandle/ServerSocketHandle interface.
196
197     The member prototypes given in the base class documentation only specify the call signature not
198     the way, the member must be defined (FileHandle really is not a FileHandle but an arbitrary
199     SocketHandle).
200
201     If the existence of a member depends on other policies, you should use the
202     <code>If</code><i>SomePolicy</i><code>Is</code> and
203     <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to dynamically enable/disable the
204     member depending on some other policy:
205
206     \code
207       struct ExampleAddressingPolicy
208       {
209           template <class SPolicy>
210           void connect(senf::SocketHandle<SPolicy> handle, Address & addr,
211                        typename senf::IfCommmunicationPolicyIs<
212                            SPolicy, senf::ConnectedCommunicationPolicy>::type * = 0);
213       };
214     \endcode
215
216     The \c connect member in this example will only be enabled, it the communication policy of the
217     socket handle is ConnectedCommunicationPolicy (or a derived type). See <a
218     href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a> for a discussion of
219     the third argument (\c senf::ConnectedCommunicationPolicyIs is based on the \c boost::enable_if
220     template).
221
222     \see \ref extend_policy \n
223          <a href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
224          <a href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
225          <a href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
226
227     \idea We could combine all the \e Axis \c Is templates into a single template. Since the \e
228     trait argument will automatically specify the axis to be used, it is not necessary to specify
229     that axis in the template functor's name. We could even combine this with \c
230     SocketPolicyIsBaseOf.
231  */
232
233 /** \defgroup policy_impl_group Policy Implementation classes
234     \ingroup policy_group
235
236     Here you will find all policy classes. Also included are some supporting classes which are used
237     as base classes to build other policy classes.
238  */
239
240 #ifndef HH_SENF_Socket_SocketPolicy_
241 #define HH_SENF_Socket_SocketPolicy_ 1
242
243 // Custom includes
244
245 //#include "SocketPolicy.mpp"
246 ///////////////////////////////hh.p////////////////////////////////////////
247
248 namespace senf {
249
250     /// \addtogroup policy_group
251     /// @{
252
253     // This may be adapted to change the supported policies (however, ClientSocketHandle and
254     // ServerSocketHandle will probably have to be adjusted accordingly)
255
256     /** \brief List all policy axis
257
258         \internal
259
260         This define symbol is used to configure the policy axis. The base class for each of these
261         axis must be defined explicitly (e.g. AddressingPolicyBase). The implementation files will
262         then automatically generate all the other classes from this list.
263
264         \see policy_group
265      */
266 #   define SENF_SOCKET_POLICIES                 \
267         (AddressingPolicy)                      \
268         (FramingPolicy)                         \
269         (CommunicationPolicy)                   \
270         (ReadPolicy)                            \
271         (WritePolicy)
272
273     // Wer define these classes explicitly (and not with some macro
274     // magic) because
275     // a) AddressingPolicyBase is different from all the others
276     // b) We want to document each one explicitly
277
278     /** \brief Policy defining socket addressing
279
280         AddressingPolicyBase is the baseclass of all addressing policy classes. When defining a new
281         addressing policy, the following members can be defined. All methods must be static.
282
283         <table class="senf">
284         <tr><td>typedef</td> <td><tt>Address</tt></td>                                   <td>Address type</td></tr>
285         <tr><td>method</td>  <td><tt>void local(FileHandle, Address &)</tt></td>         <td>Get local socket address</td></tr>
286         <tr><td>method</td>  <td><tt>void peer(FileHandle, Address &)</tt></td>          <td>Get remote socket address</td></tr>
287         <tr><td>method</td>  <td><tt>void bind(FileHandle, Address const &)</tt></td>    <td>Bind socket to local address</td></tr>
288         <tr><td>method</tr>  <td><tt>void connect(FileHandle, Address const &)</tt></td> <td>Connect to remote address</td></tr>
289         </table>
290
291         \see policy_group
292      */
293     struct AddressingPolicyBase
294     {
295         virtual ~AddressingPolicyBase();
296
297         class Address { Address(); };
298     };
299
300     /** \brief Policy defining the framing format
301
302         This policy does not define any operations since it does have no influence on any method
303         signature. It does however affect the semantics of the \c read() and \c write() operations.
304
305         \note This policy axis probably only has two sensible states: StreamFramingPolicy and
306         DatagramFramingPolicy.
307
308         \see policy_group
309      */
310     struct FramingPolicyBase
311     {
312         virtual ~FramingPolicyBase();
313     };
314
315     /** \brief Policy defining, how peers are selected
316
317         The CommunicationPolicy may define two members:
318
319         <table class="senf">
320         <tr><td>method</td> <td><tt>void listen(FileHandle, unsigned backlog)</tt></td> <td>Switch socket into listening state</td></tr>
321         <tr><td>method</td> <td><tt>int accept(FileHandle, Address &)</tt></td>         <td>Accept a new connection</td></tr>
322         <tr><td>method</td> <td><tt>int accept(FileHandle)</tt></td>                    <td>Accept a new connection</td></tr>
323         </table>
324
325         The \c listen member is straight forward. The \c accept() member must return a new file
326         descriptor (which will be used to create a new SocketHandle of the correct
327         type).
328
329         \note This Policy only has two meaningful states: ConnectedCommunicationPolicy and
330         UnconnectedCommunicationPolicy. It is probably not sensible to define a new
331         CommunicationPolicy type.
332
333         \see policy_group
334      */
335     struct CommunicationPolicyBase
336     {
337         virtual ~CommunicationPolicyBase();
338     };
339
340     /** \brief Policy defining the readability
341
342         The ReadPolicy defines, whether the socket is readable. It may define two members:
343
344         <table class="senf">
345         <tr><td>method</td> <td><tt>unsigned read(FileHandle, char * buffer, unsigned size)</tt></td>                <td>read data from socket</td></tr>
346         <tr><td>method</td> <td><tt>unsigned readfrom(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
347         </table>
348
349         The second member should only be enabled if the communication policy is
350         UnconnectedCommunicationPolicy (otherwise it does not make sense since the communication partner
351         is fixed) (see AddressingPolicyBase on how to do this).
352
353         \note This Policy only has two meaningful states: ReadablePolicy and NotReadablePolicy. It
354         probably does not make sense to define new read policy types.
355
356         \see policy_group
357      */
358     struct ReadPolicyBase
359     {
360         virtual ~ReadPolicyBase();
361     };
362
363     /** \brief Policy defining the writability
364
365         The WritePolicy defines, whether the socket is writable. It may define two members:
366
367         <table class="senf">
368         <tr><td>method</td> <td><tt>unsigned write(FileHandle, char * buffer, unsigned size)</tt></td>              <td>read data from socket</td></tr>
369         <tr><td>method</td> <td><tt>unsigned writeto(FileHandle, char * buffer, unsigned size, Address &)</tt></td> <td>read data from unconnected socket</td></tr>
370         </table>
371
372         The second member should only be enabled if the communication policy is
373         UnconnectedCommunicationPolicy (otherwise it does not make sense since the communication partner
374         is fixed) (see AddressingPolicyBase on how to do this).
375
376         \note This Policy only has two meaningful states: WritablePolicy and NotWritablePolicy. It
377         probably does not make sense to define new write policy types.
378
379         \see policy_group
380      */
381     struct WritePolicyBase
382     {
383         virtual ~WritePolicyBase();
384     };
385
386     // The implementation file will for each Policy declared above
387     // define the following (SomePolicy is one of the above):
388     //
389     // struct SomePolicyBase;
390     // typedef UndefinedSomePolicy;
391     // template SomePolicyIs< SocketPolicy, Axis >
392     // template IfSomePolicyIs< SocketPolicy, Axis >
393     // template IfSomePolicyIsNot< SocketPolicy, Axis >
394     //
395     // Additionally the following are defined:
396     //
397     // class SocketPolicyBase
398     // template SocketPolicy< ..policies.. >
399     // template MakeSocketPolicy< ..args.. >
400     // template SocketPolicyIsBaseOf< Base, Derived >
401
402 #   ifdef DOXYGEN
403
404     // The following stub definitions are only visible to doxygen
405
406     /** \brief Alias of AddressingPolicyBase for better readability
407         \see \ref policy_group
408      */
409     typedef AddressingPolicyBase UnspecifiedAddressingPolicy;
410
411     /** \brief Check single policy axis
412
413         This template is an example of the \e Axis \c Is family of template metafunctions. It will
414         check, whether \c Trait is a valid compatible Policy class of \c SocketPolicy. \c Trait must
415         be derived from AddressingPolicyBase (respectively \c Policy \c Base).
416
417         \see \ref policy_group
418      */
419     template <class SocketPolicy, class Trait>
420     struct AddressingPolicyIs
421     {};
422
423     /** \brief Enable template overload depending on policy value
424
425         This template is an example of the \c If \e Axis \c Is family of templates. It is used like
426         <a href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a> to enable a
427         templated overload only, if the AddressingPolicy of \e Axis is compatible with \c Trait
428         (that is the AddressingPolicy of \c Policy is derived from \c Trait).
429
430         \see policy_group
431      */
432     template <class SocketPolicy, class Trait>
433     struct IfAddressingPolicyIs
434     {};
435
436     /** \brief Inversion of \c IfAddressingPolicyIs
437         \see policy_group
438      */
439     template <class SocketPolicy, class Trait>
440     struct IfAddressingPolicyIsNot
441     {};
442
443     /** \brief Baseclass of all SocketPolicies
444
445         \internal
446
447         This class provides the baseclass of all socket policies (bundles). It serves two purposes:
448         \li It allows us to easily identify a socket policy bundle by checking a classes baseclass.
449         \li It provides an abstract (virtual) interface to access the policy axes
450
451         \see policy_group
452      */
453     struct SocketPolicyBase
454     {
455         /** \brief Polymorphic access to policy axes
456
457             This is an example of a policy axes accessor. It returns a reference to the policy axes
458             used by the concrete protocol bundle. This reference can then be checked using RTTI
459             information.
460          */
461         AddressingPolicyBase const & theAddressingPolicy() const = 0;
462
463         virtual ~SocketPolicyBase();
464     };
465
466     /** \brief Collection of policy classes
467
468         The SocketPolicy template defines the complete Policy used by the socket library. It
469         contains one policy class for each policy axis. This template takes one policy from each
470         axis as it's template arguments (this example implementation only has AddressingPolicy as an
471         argument).
472
473         A SocketPolicy can be complete or incomplete. An incomplete SocketPolicy will have at least
474         one axis set to \c Undefined \e Axis (or a generic derived class which is used to group some
475         other policies but does not (completely) define the policy behavior). A complete
476         SocketPolicy will have a concrete definition of the desired behavior for each policy axis.
477
478         \see policy_group
479      */
480     template < class AddressingPolicy >
481     struct SocketPolicy
482     {
483         /** \brief Check dynamic policy compatibility
484
485             This check will validate, that a socket with \a other as it's policy is convertible to a
486             socket with the current SocketPolicy as it's policy. This is true, if for each policy
487             axis, the policy class of that axis as defined in the \a other policy is convertible to
488             the policy class of that same axis in the current SocketPolicy instance (as is defined
489             by the template arguments). This again is true, if the \a other policy class is derived
490             from (or is the same as) the policy class taken from the current SocketPolicy instance.
491
492             In other words, this call checks, that the current SocketPolicy (as defined via the
493             template arguments) is more generic than the \a other socket policy.
494
495             \param[in] other SocketPolicy to check
496             \throws std::bad_cast if \a other is not a compatible policy
497          */
498         static void checkBaseOf(SocketPolicyBase const & other);
499     };
500
501     /** \brief Metafunction to create SocketPolicy
502
503         This template metafunction simplifies the creation of a SocketPolicy instantiation. It takes
504         any number (that is up to 6) of Policy classes as arguments in any Order. It will create a
505         SocketPolicy from these policy classes. Any axis not specified will be left as \c
506         Unspecified \e Axis.
507
508         \see policy_group
509      */
510     template <class Arg1, class Arg2, class ArgN>
511     struct MakeSocketPolicy
512     {};
513
514     /** \brief Check policy compatibility
515
516         This template metafunction checks, whether the SocketPolicy \c Derived is more specialized
517         than \c Base (and therefore a SocketHandle with policy \c Derived is convertible to a
518         SocketHandle with policy \c Base).
519
520         The metafunction will return true (that is inherits from \c boost::true_type, see the <a
521         href="http://www.boost.org/libs/mpl/doc/index.html">Boost.MPL</a> library documentation for
522         more information) if each policy class in \c Base is a baseclass of (or the same as) the
523         corresponding policy class in \c Derived.
524
525         \see policy_group
526      */
527     template <class Base, class Derived>
528     struct SocketPolicyIsBaseOf
529     {};
530
531 #   endif
532
533     /// @}
534 }
535
536 //////////////////////////////hh.e////////////////////////////////////////
537 #include "SocketPolicy.ih"
538 //#include "SocketPolicy.cci"
539 #include "SocketPolicy.ct"
540 //#include "SocketPolicy.cti"
541 #endif
542
543 \f
544 // Local Variables:
545 // mode: c++
546 // fill-column: 100
547 // c-file-style: "senf"
548 // indent-tabs-mode: nil
549 // ispell-local-dictionary: "american"
550 // compile-command: "scons -u test"
551 // comment-column: 40
552 // End: