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