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