Added Socket Library overview documentation
g0dil [Thu, 1 Mar 2007 10:15:40 +0000 (10:15 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@210 270642c3-0616-0410-b53a-bc976706d245

Socket/Handle.dia [new file with mode: 0644]
Socket/Mainpage.dox
Socket/SConscript
Socket/SocketPolicy.hh
doclib/Doxyfile.global

diff --git a/Socket/Handle.dia b/Socket/Handle.dia
new file mode 100644 (file)
index 0000000..251f3f1
Binary files /dev/null and b/Socket/Handle.dia differ
index 8f8f736..76334f6 100644 (file)
@@ -2,26 +2,22 @@ namespace senf {
 
 /** \mainpage The SENF Socket Library
 
-    The Socket library provides a high level and object oriented
-    abstraction of the BSD socket API. The abstraction is based on
-    several concepts:
-
-    \li The basic visible interface is a \link handle_group handle
-        object \endlink
-    \li The socket interface relies on a \link policy_group policy
-        framework \endlink to configure it's functionality
-    \li The rest of the socket API is accessible using a classic
-        inheritance hierarchy of \link protocol_group protocol classes
-        \endlink
-
-    The handle/body architecture provides automatic reference counted
-    management of socket instances, the policy framework provides
-    highly efficient access to the most important socket functions
-    (like reading and writing) and the inheritance hierarchy provides
-    convenient access to the multitude of special and protocol
-    dependent options.
-
-    \see \ref usage \n
+    The Socket library provides a high level and object oriented abstraction of the BSD socket
+    API. The abstraction is based on several concepts:
+
+    \li The basic visible interface is a \link handle_group handle object \endlink
+    \li The socket interface relies on a \link policy_group policy framework \endlink to configure
+        it's functionality
+    \li The rest of the socket API is accessible using a classic inheritance hierarchy of \link
+        protocol_group protocol classes \endlink
+
+    The handle/body architecture provides automatic reference counted management of socket
+    instances, the policy framework provides highly efficient access to the most important socket
+    functions (like reading and writing) and the inheritance hierarchy provides convenient access to
+    the multitude of special and protocol dependent options.
+
+    \see \ref structure \n
+         \ref usage \n
          \ref handle_group \n
          \ref policy_group \n
          \ref protocol_group \n
@@ -29,41 +25,113 @@ namespace senf {
          \ref implementation
  */
 
+/** \page structure Overview of the Socket Library Structure
+
+    \image html Handle.png
+
+    This diagram tries to give a structural overview of the Socket Library, it does \e not directly
+    show, how the library is implemented. This will be explained later.
+
+    The outside interface to the library is a Handle object. This is the only object, the library
+    user directly interacts with. Every handle references some socket. This is like the ordinary
+    POSIX API: the file descriptor (also called file handle, an integer number) references a socket
+    structure which lives in kernel space. In this library, the Handle object (which is not a simple
+    integer any more but an object) references the Socket (which is part of the
+    implementation). Several handles may reference the same Socket. In contrast to the kernel API,
+    the library employs reference counting to release a socket when the last Handle to it goes out
+    of scope.
+
+    The behavior of a Socket is defined by it's Protocol. It is divided into two parts: the
+    <em>policy interface</em> and the <em>protocol interface</em>. Together they provide the
+    complete API for a specific type of Socket as defined by the Protocol. The <em>policy
+    interface</em> provides highly efficient access to the most frequently used operations whereas
+    the <em>protocol interface</em> completes the interface by providing a complete set of all
+    protocol specific operations not found in the policy interface. This structure allows us to
+    combine the benefits of two design methodologies: The policy interface utilizes a policy based
+    design technique and is highly efficient albeit more complex to implement, whereas the protocol
+    interface is based on a more common inheritance architecture which is not as optimized for
+    performance but much simpler to implement. We reduce the complexity of the implementation by
+    reducing the policy interface to a minimal sensible subset of the complete API.
+
+    \section over_policy The Policy Interface
+    
+    The policy of a Socket consists of several parts, called <em>policy axis</em>. Each axis
+    corresponds to one specific interface aspect of the Socket. The exact meaning of the policy axis
+    are defined elsewhere (see \ref policy_group). The Protocol will always provide a complete set
+    of <em>policy classes</em>, one for each axis.
+
+    This <em>complete socket policy</em> defines the policy interface of the protocol. This
+    interface is carried over into the Handle. The socket policy as defined in the Handle however
+    may be <em>incomplete</em>. This mans, that the \e accessible interface of the Socket depends on
+    the type of Handle used. The inherent interface does not change but the view of this interface
+    does if the Handle does not provide the \e complete policy interface. This feature is very
+    important. It allows to define generic Handle types. A generic Handle with an incompletely
+    defined policy can point to an arbitrary Socket as long as all those policy axis which \e are
+    defined match those defined in that Socket's protocol. Using such a generic handle decouples the
+    implementation parts using this handle from the other socket aspects (e.g. you may define a
+    generic socket handle for TCP based communication leaving the addressingPolicy undefined which
+    makes your code independent of the type of addressing, IPv4 or IPv6).
+
+    \section over_protocol The Protocol Interface
+
+    The protocol interface is provided by a set of <em>protocol facets</em>. Each facet provides a
+    part of the interface. Whereas the policy interface is strictly defined (the number and type of
+    policy axis is fixed and also the possible members provided by the policy interface is fixed),
+    the protocol interface is much more flexible. Any member needed to provide a complete API for
+    the specific protocol may be defined, the number and type of facets combined to provide the
+    complete interface is up to the Protocol implementor. This flexibility is necessary to provide a
+    complete API for every possible protocol.
+
+    However this flexibility comes at a cost: To access the protocol interface the user must know
+    the exact protocol of the socket. With other words, the protocol is only accessible if the
+    handle you use is a protocol specific handle. A protocol specific Handle differs from a generic
+    Handle in two ways: It always \e must have a complete policy and it has an additional reference
+    to the protocol type of the socket. This reference gives access to the complete policy
+    interface.
+
+    \section over_impl Implementation of the Socket Libarary Structure
+
+    In the Implementation, the socket policy is identified by an instance of the senf::SocketPolicy
+    template. The Socket representation is internally represented in a senf::SocketBody which is not
+    outside visible. The Handle is provided by a hierarchy of handle templates. Each Handle template
+    uses template arguments for the policy and/or protocol as needed (see \ref handle_group).
+
+    The protocol interface is implemented using inheritance: The Protocol class inherits from each
+    protocol facet using multiple (virtual public) inheritance. The Protocol class therefore
+    provides the complete protocol API in a unified (see \ref protocol_group).
+
+    The Handle references the policy and the protocol only via it's template argument, the
+    information is part of the type. This information is not available as a data member in the
+    Handle object.
+ */
+
 /** \page usage Using the Socket Library
 
-    Whenever you use the socket library, what you will be dealing with
-    are FileHandle derived instances. The socket library relies
-    on reference counting to automatically manage the underlying
-    socket representation. This frees you of having to manage the
-    socket lifetime explicitly.
+    Whenever you use the socket library, what you will be dealing with are FileHandle derived
+    instances. The socket library relies on reference counting to automatically manage the
+    underlying socket representation. This frees you of having to manage the socket lifetime
+    explicitly.
 
     \section usage_create Creating a Socket Handle
 
-    To create a new socket handle (opening a socket), you will need to
-    use ProtocolClientSocketHandle or
-    ProtocolServerSocketHandle. You will probably not use these
-    templates as is but use proper typedefs (for example
-    TCPv4ClientSocketHandle or PacketSocketHandle). The
-    documentation for these socket handles are found in the protocol
-    class (for example TCPv4SocketProtocol or
-    PacketProtocol).
+    To create a new socket handle (opening a socket), you will need to use
+    ProtocolClientSocketHandle or ProtocolServerSocketHandle. You will probably not use these
+    templates as is but use proper typedefs (for example TCPv4ClientSocketHandle or
+    PacketSocketHandle). The documentation for these socket handles are found in the protocol class
+    (for example TCPv4SocketProtocol or PacketProtocol).
 
     \section usage_reusable Writing Reusable Components
 
-    To make your code more flexible, you should not pass around your
-    socket in this form. Most of your code will be using only a small
-    subset of the ProtocolClientSocketHandle or
-    ProtocolServerSocketHandle API. 
+    To make your code more flexible, you should not pass around your socket in this form. Most of
+    your code will be using only a small subset of the ProtocolClientSocketHandle or
+    ProtocolServerSocketHandle API.
     
-    If instead of using the
-    fully specified handle type you use a more incomplete type, you
-    allow your code to be used with all sockets which fulfill the
-    minimal requirements of your code. These types are based on the 
-    ClientSocketHandle and ServerSocketHandle templates which implement
-    the policy interface without providing the concrete protocol interface.
-    To use those templates you may define a special reduced policy or handle for
-    your code. By giving only an incomplete policy you thereby reduce the 
-    interface to that required by your module:
+    If instead of using the fully specified handle type you use a more incomplete type, you allow
+    your code to be used with all sockets which fulfill the minimal requirements of your code. These
+    types are based on the ClientSocketHandle and ServerSocketHandle templates which implement the
+    policy interface without providing the concrete protocol interface.  To use those templates you
+    may define a special reduced policy or handle for your code. By giving only an incomplete policy
+    you thereby reduce the interface to that required by your module:
 
     \code
       typedef ClientSocketHandle<
@@ -74,49 +142,38 @@ namespace senf {
 
     \endcode
 
-    This defines \c MyReadableHandle as a ClientSocketHandle
-    which will have only read functionality. Your code expects a
-    stream interface (in contrast to a packet or datagram based
-    interface). You will not have \c write or \c readfrom members. \c
-    write will be disabled since the WritePolicy is unknown, \c
-    readfrom will be disabled since a socket with the
-    ConnectedCommunicationPolicy does not have a \c readfrom
-    member.
+    This defines \c MyReadableHandle as a ClientSocketHandle which will have only read
+    functionality. Your code expects a stream interface (in contrast to a packet or datagram based
+    interface). You will not have \c write or \c readfrom members. \c write will be disabled since
+    the WritePolicy is unknown, \c readfrom will be disabled since a socket with the
+    ConnectedCommunicationPolicy does not have a \c readfrom member.
  */
 
 
 
 /** \page extend Extending the Library
 
-    There are two layers, on which the socket library can be
-    extended: On the protocol layer and on the policy layer. Extending
-    the protocol layer is quite simple and works as long as the
-    desired protocol does use the same BSD API used by the standard
-    internet protocols as implemented in the standard policies
-    (i.e. it uses ordinary read() and write() or rcvfrom() or sendto()
-    calls and so on).
+    There are two layers, on which the socket library can be extended: On the protocol layer and on
+    the policy layer. Extending the protocol layer is quite simple and works as long as the desired
+    protocol does use the same BSD API used by the standard internet protocols as implemented in the
+    standard policies (i.e. it uses ordinary read() and write() or rcvfrom() or sendto() calls and
+    so on).
 
-    If however the implementation of a policy feature needs to be
-    changed, a new policy class has to be written. This also is not
-    very complicated however the integration is more complex.
+    If however the implementation of a policy feature needs to be changed, a new policy class has to
+    be written. This also is not very complicated however the integration is more complex.
 
     \section extend_protocol Writing a new protocol class
 
-    Most protocols can be implemented by just implementing a new
-    protocol class. The protocol class must be derived from
-    ConcreteSocketProtocol and takes the socket policy (as
-    created by MakeSocketPolicy) as a template argument. See the
-    documentation of this class for the interface.
-
-    \attention You may want to use multiple inheritance as it is used
-    in the implementation of the standard protocols (See \ref
-    protocol_group). You must however be extra careful to ensure, that
-    every class ultimately has SocketPolicy as a public \e
-    virtual base.
-
-    After the protocol class has been defined, you will probably want to
-    provide typedefs for the new protocol sockets. If the new protocol
-    is connection oriented, this will be like
+    Most protocols can be implemented by just implementing a new protocol class. The protocol class
+    must be derived from ConcreteSocketProtocol and takes the socket policy (as created by
+    MakeSocketPolicy) as a template argument. See the documentation of this class for the interface.
+
+    \attention You may want to use multiple inheritance as it is used in the implementation of the
+    standard protocols (See \ref protocol_group). You must however be extra careful to ensure, that
+    every class ultimately has SocketPolicy as a public \e virtual base.
+
+    After the protocol class has been defined, you will probably want to provide typedefs for the
+    new protocol sockets. If the new protocol is connection oriented, this will be like
     \code
     typedef ProtocolClientSocketHandle<MyProtocolClass> MyProtocolClientSocketHandle;
     typedef ProtocolServerSocketHandle<MyProtocolClass> MyProtocolServerSocketHandle;
@@ -124,35 +181,28 @@ namespace senf {
 
     \section extend_policy Extending the policy framework
 
-    If you have to extend the policy framework, you will need to be
-    aware of some important limitations of the socket library:
-
-    \li When you define a new policy for some axis, this new policy
-        <em>must not</em> be derived from one of the existing concrete
-        policy classes (except of course the respective policy axis
-        base class). This is important since the policy type is \e not
-        polymorphic. The policy to be used is selected by the compiler
-        using the \e static type, which is exactly what is desired,
-        since this allows calls to be efficiently inlined.
-
-    \li Therefore, extending the policy framework will make the new
-        socket probably \e incompatible with generic code which relies
-        on the policy axis which is extended. Example: If you write a
-        new write policy because your protocol does not use ordinary
-        write() system calls but some protocol specific API, Then any
-        generic function relying on WritablePolicy will \e not
-        work with the new socket, since the socket does \e not have
-        this policy, it has some other kind of write policy.
-
-    Therefore you need to be careful of what you are doing. The first
-    step is to find out, which policy you will have to implement. For
-    this, find the ClientSocketHandle and/or
-    ServerSocketHandle members you want to change (see \ref
-    ClientSocketHandle and \ref ServerSocketHandle).  Not
-    all policy axis directly contribute to the SocketHandle
-    interface. However, some policy members additionally depend on
-    other policy axis (example: AddressingPolicy::connect is only
-    defined if the communication policy is
+    If you have to extend the policy framework, you will need to be aware of some important
+    limitations of the socket library:
+
+    \li When you define a new policy for some axis, this new policy <em>must not</em> be derived
+        from one of the existing concrete policy classes (except of course the respective policy
+        axis base class). This is important since the policy type is \e not polymorphic. The policy
+        to be used is selected by the compiler using the \e static type, which is exactly what is
+        desired, since this allows calls to be efficiently inlined.
+
+    \li Therefore, extending the policy framework will make the new socket probably \e incompatible
+        with generic code which relies on the policy axis which is extended. Example: If you write a
+        new write policy because your protocol does not use ordinary write() system calls but some
+        protocol specific API, Then any generic function relying on WritablePolicy will \e not work
+        with the new socket, since the socket does \e not have this policy, it has some other kind
+        of write policy.
+
+    Therefore you need to be careful of what you are doing. The first step is to find out, which
+    policy you will have to implement. For this, find the ClientSocketHandle and/or
+    ServerSocketHandle members you want to change (see \ref ClientSocketHandle and \ref
+    ServerSocketHandle).  Not all policy axis directly contribute to the SocketHandle
+    interface. However, some policy members additionally depend on other policy axis (example:
+    AddressingPolicy::connect is only defined if the communication policy is
     ConnectedCommunication).
 
     \see policy_group
@@ -162,35 +212,31 @@ namespace senf {
 
     <table class="glossary">
 
-    <tr><td>policy</td> <td>collection of policy classes, one for each
-    policy axis, instantiation of the SocketPolicy template</td></tr>
+    <tr><td>policy</td> <td>collection of policy classes, one for each policy axis, instantiation of
+    the SocketPolicy template</td></tr>
 
-    <tr><td>policy axis</td> <td>one aspect defined in the socket
-    policy, typedef and member of the SocketPolicy template</td></tr>
+    <tr><td>policy axis</td> <td>one aspect defined in the socket policy, typedef and member of the
+    SocketPolicy template</td></tr>
 
-    <tr><td>policy class</td> <td>implementation of a single policy
-    axis, class derived from the axis base class</td></tr>
+    <tr><td>policy class</td> <td>implementation of a single policy axis, class derived from the
+    axis base class</td></tr>
 
-    <tr><td>complete policy</td> <td>socket policy where each
-    axis is specified completely</td></tr>
+    <tr><td>complete policy</td> <td>socket policy where each axis is specified completely</td></tr>
 
-    <tr><td>incomplete policy</td> <td>socket policy, where at
-    least one axis is not fully specified</td></tr>
+    <tr><td>incomplete policy</td> <td>socket policy, where at least one axis is not fully
+    specified</td></tr>
 
-    <tr><td>protocol class</td> <td>definition of a protocol as a
-    class, class inheriting from ConcreteSocketProtocol.</td></tr>
+    <tr><td>protocol class</td> <td>definition of a protocol as a class, class inheriting from
+    ConcreteSocketProtocol.</td></tr>
 
-    <tr><td>protocol facet</td> <td>a class providing some subset of
-    the protocol interface, class derived from SocketProtocol but not
-    from ConcreteSocketProtocol</td></tr>
+    <tr><td>protocol facet</td> <td>a class providing some subset of the protocol interface, class
+    derived from SocketProtocol but not from ConcreteSocketProtocol</td></tr>
 
     <tr><td>policy interface</td> <td>interface directly provided by
-    ClientSocketHandle/ServerSocketHandle and defined through the
-    policy</td>
+    ClientSocketHandle/ServerSocketHandle and defined through the policy</td>
 
-    <tr><td>protocol interface</td> <td>interface provided by the
-    protocol class and accessible via the
-    ProtocolClientSocketHandle::protocol()/ProtocolServerSocketHandle::protocol()
+    <tr><td>protocol interface</td> <td>interface provided by the protocol class and accessible via
+    the ProtocolClientSocketHandle::protocol()/ProtocolServerSocketHandle::protocol()
     member</td></tr>
 
     </table>
@@ -204,19 +250,15 @@ namespace senf {
 
     \section impl_notes Arbitrary Implementation Notes
 
-    \li The implementation tries to isolate the library user as much
-        as possible from the system header files since those headers
-        define a lot of define symbols and introduce a host of symbols
-        into the global namespace. This is, why some classes define
-        their own \c enum types to replace system defined define
-        constants. This also precludes inlining some functionality.
-
-    \li To reduce overhead, template functions/members which are
-        more than one-liners are often implemented in terms of a
-        non-template function/member. This is also used to further the
-        isolation from system headers as defined above (template code
-        must always be included into every compilation unit together
-        with all headers need for the implementation).
+    \li The implementation tries to isolate the library user as much as possible from the system
+        header files since those headers define a lot of define symbols and introduce a host of
+        symbols into the global namespace. This is, why some classes define their own \c enum types
+        to replace system defined define constants. This also precludes inlining some functionality.
+
+    \li To reduce overhead, template functions/members which are more than one-liners are often
+        implemented in terms of a non-template function/member. This is also used to further the
+        isolation from system headers as defined above (template code must always be included into
+        every compilation unit together with all headers need for the implementation).
  */
 
 }
index 5baedce..56ae5d4 100644 (file)
@@ -19,4 +19,5 @@ SENFSCons.Doxygen(env, extra_sources = [
     env.Dia2Png('FhHierarchy.dia'),
     env.Dia2Png('SocketPolicy.dia'),
     env.Dia2Png('Protocols.dia'),
+    env.Dia2Png('Handle.dia'),
 ])
index 6ef2981..507eafd 100644 (file)
 /** \file
     \brief Policy Framework public header
 
-    \todo We should probably remove BufferingPolicy from the
-        interface, it does not make much sense (how did I come to
-        include it ??)
-
-    \todo Do we want to support separate read and write policies. This
-        allows to treat pipes within this framework however, is this
-        worth the effort?
-
-    \idea Creating a new Socket will create 4 (!) new instances (The
-        handle, the body, the policy and the protocol) of which 3
-        (argh) (body, policy and protocol) live on the heap. This is
-        expensive. We should convert all the policy classes to
-        singletons and assign the same instance to all socket bodies
-        with the same policy. This would reduce the number of heap
+    \todo We should probably remove BufferingPolicy from the interface, it does not make much sense
+        (how did I come to include it ??)
+
+    \todo Do we want to support separate read and write policies. This allows to treat pipes within
+        this framework however, is this worth the effort?
+
+    \idea Creating a new Socket will create 4 (!) new instances (The handle, the body, the policy
+        and the protocol) of which 3 (argh) (body, policy and protocol) live on the heap. This is
+        expensive. We should convert all the policy classes to singletons and assign the same
+        instance to all socket bodies with the same policy. This would reduce the number of heap
         allocations per socket handle to two.
  */
 
 
     \section policy_group_introduction Introduction to the Policy Framework
 
-    The policy framework conceptually implements a list of parallel
-    inheritance hierarchies each covering a specific interface aspect
-    of the socket handle. The socket handle itself only provides
-    minimal functionality. All further functionality is relayed to a
-    policy class, or more precisely, to a group of policy classes, one
-    for each policy axis. The policy axis are
+    The policy framework conceptually implements a list of parallel inheritance hierarchies each
+    covering a specific interface aspect of the socket handle. The socket handle itself only
+    provides minimal functionality. All further functionality is relayed to a policy class, or more
+    precisely, to a group of policy classes, one for each policy axis. The policy axis are
 
-    <dl>
-    <dt><em>addressingPolicy</em></dt>
-    <dd>configures, whether a socket is
-    addressable and if so, configures the address type</dd>
+    <dl><dt><em>addressingPolicy</em></dt><dd>configures, whether a socket is addressable and if
+    so, configures the address type</dd>
 
-    <dt><em>framingPolicy</em></dt>
-    <dd>configures the type of framing the socket provides: either no
-    framing providing a simple i/o stream or packet framing</dd>
+    <dt><em>framingPolicy</em></dt> <dd>configures the type of framing the socket provides: either
+    no framing providing a simple i/o stream or packet framing</dd>
 
-    <dt><em>communicationPolicy</em></dt>
-    <dd>configures,if and how the communication partner is
+    <dt><em>communicationPolicy</em></dt><dd>configures,if and how the communication partner is
     selected</dd>
 
-    <dt><em>readPolicy</em></dt>
-    <dd>configures the readability of the socket</dd>
+    <dt><em>readPolicy</em></dt><dd>configures the readability of the socket</dd>
 
-    <dt><em>writePolicy</em></dt>
-    <dd>configures the writability of the socket</dd>
+    <dt><em>writePolicy</em></dt><dd>configures the writability of the socket</dd>
 
-    <dt><em>bufferingPolicy</em></dt>
-    <dd>configures, if and how buffering is configured for a socket</dd>
-    </dl>
+    <dt><em>bufferingPolicy</em></dt><dd>configures, if and how buffering is configured for a
+    socket</dd> </dl>
 
-    In a concrete policy, each of these policy axis is assigned a value,
-    the policy value. This value is identified by a class type. For example,
-    possible values for <em>framingPolicy</em> are <tt>DatagramFramingPolicy</tt>
-    or <tt>StreamFramingPolicy</tt> which are classes derived from the axis
-    base class <tt>FramingPolicyBase</tt>. This base class doubles as
-    <tt>UnspecifiedFramingPolicy</tt> (which is just a typedef alias).
-    If a policy axis is assigned this Unspecified type, the axis is left
-    unspecified, the policy will be incomplete.
+    The template senf::SocketPolicy combines these policy axis to form a concrete socket policy. In
+    a concrete policy, each of these policy axis is assigned a value, the policy value. This value
+    is identified by a class type, a policy class. E.g. possible values for <em>framingPolicy</em>
+    are <tt>DatagramFramingPolicy</tt> or <tt>StreamFramingPolicy</tt> which are classes derived
+    from the axis base class <tt>FramingPolicyBase</tt>. This base class also doubles as
+    <tt>UnspecifiedFramingPolicy</tt> (which is just a typedef alias).  If a policy axis is assigned
+    this Unspecified type, the axis is left unspecified, the concrete policy will be incomplete.
     
-    The senf::SocketPolicy tempalte defines the complete policy of a socket. It
-    combines a set of policy classes, one for each policy
-    axis as described above. Together, they define the behavior of a socket handle. The
-    socket handle instances do not implement any socket functionality
-    themselves instead defering the implementation to the policy
-    classes. The SocketHandle interface is therefore \e not
-    implemented using virtual members, all important socket functions
-    can be inlined by the compiler to create highly efficient code.
-
-    A SocketPolicy can be incomplete. In this case it does \e not
-    completely specify the socket interface, it leaves some aspects
-    open. A SocketHandle based on such a policy will have a reduced
-    interface: It will only support those members for wich the
-    corresponding policies are defined.
-
-    Two SocketHandle's with different policies can be \e
-    compatible. If they are, the more derived SocketHandle can be
-    converted (assigned to) the more basic SocketHandle.
-
-    \doc Example (concrete policy, incomplete policy, compatibility/assignment)
+    The senf::SocketPolicy template defines the behavior of a socket handle. The socket handle
+    instances do not implement any socket functionality themselves instead defering the
+    implementation to the policy classes. The SocketHandle interface is therefore \e not implemented
+    using virtual members, all important socket functions can be inlined by the compiler to create
+    highly efficient code.
+
+    A senf::SocketPolicy instance can be incomplete. In this case it does \e not completely specify
+    the socket interface, it leaves some aspects open by assigning the Unspecified value to one or
+    more of the policy axis. A senf::SocketHandle based on such a policy will have a reduced
+    interface: It will only support those members for wich the corresponding policies are defined.
+
+    To build a senf::SocketPolicy instance the senf::MakeSocketPolicy helper is provided. This
+    helper template takes any number (it is really limited to 6 Arguments but more arguments don't
+    make sense) of policy classes as it's argument. The MakeSocketPolicy helper will take the
+    arguments in the order they are specified and for each argument will check to which axis the
+    policy class belongs (by checking the base classes of that class) and assign it to the correct
+    policy axis in the senf::SocketPolicy template. If any policy axis are not specified, they are
+    defaulted to their corresponding Unspecified value. This helper frees you to specify the policy
+    classes in any order. An additional feature is, that you may specify a complete policy as a
+    first argument. This policy will then be used to provide default values for unspecified axis.
+
+    Two senf::SocketHandle's with different policies can be \e compatible. If they are, the more
+    specific SocketHandle can be converted (assigned to) the more basic SocketHandle. A SocketHandle
+    is more specific then another SocketHandle if the policy of the former is more specific then
+    that of the latter which means, that for each policy axis separately, the value of that axis of
+    the more specific policy is derived from or the same as the value of that axis in the more basic
+    policy. This is like converting a derived class pointer to a base class pointer, only it happens
+    separately but at the same time for each policy axis:
+
+    \code
+    // This defines an incomplete policy where addressingPolicy, writePolicy and bufferingPolicy
+    // are unspecified
+    typedef senf::MakeSocketPolicy<
+        senf::StreamFramingPolicy,
+        senf::ConnectedCommunicationPolicy,
+        senf::ReadablePolicy
+        >::policy MyReadableSocketPolicy
+
+    typedef senf::ClientSocketHandle<MyReadableSocketPolicy> MyReadableHandle;
+
+    // TCPv4ClientSocketHandle is a socket handle with the policy equivalent to
+    // senf::MakeSocketPolicy<
+    //     INet4AddressingPolicy,
+    //     StreamFramingPolicy,
+    //     ConnectedCommunicationPolicy,
+    //     ReadablePolicy,
+    //     WritablePolicy,
+    //     SocketBufferingPolicy>::policy
+    senf::TCPv4ClientSocketHandle tcpHandle (...);
+
+    MyReadableHandle myHandle (tcpHandle); // Conversion to more basic socket handle
+    \endcode
 
     \section policy_group_details The Policy Framework Classes
 
-   \doc Policy should be Axis here. Make clear, that this information is only 
-   needed when extending the library.
+    In the following discussion, deeper insight into C++ and especially the concepts of template
+    meta-programming are needed. Hoewever, this information is only needed if you want to write new
+    policy classes or want to use the policy framework explicitly for your own involved
+    optimizations ... or if you are just plain curious :-)
     
     In the following discussion we will use the following conventions:
-    \li \e Policy is one or \c AddressingPolicy, \c FramingPolicy, \c
-        CommunicationPolicy, \c ReadPolicy, \c WritePolicy or \c
-        BufferingPolicy
-    \li \e socketPolicy is any socket policy (that is, an
-        instantiation of the SocketPolicy template)
-    \li \e trait is an any policy class (that is, any class derived
-        from one of the axis base classes)
-
-    Each axis is comprised of a number of classes and templates (all
-    in namespace senf of course):
-
-    <dl>
-    <dt>\e Policy \c Base (ex: AddressingPolicyBase)</dt>
-    <dd>Baseclass of all policies in this axis</dd>
-
-    <dt>\c Unspecified \e Policy  (ex: \ref UnspecifiedAddressingPolicy)</dt>
-    <dd>An alias (typedef) for \e Policy \c Base</dd>
-
-    <dt>\e Policy \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt>
-    <dd>A template metafunction returning \c boost::true_type, if \e
-    trait (any class derived from \e Policy \c Base) is a compatible
-    policy value of the given \e socketPolicy</dd>
-
-    <dt>\c If \e Policy \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt>
-    <dd>This is a combination of \e Policy \c Is and \c boost::enable_if</dd>
-
-    <dt>\c If \e Policy \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
-    <dd>The inverse of above</dd>
-    </dl>
-
-    These classes form the basis of the policy framework. To bind the
-    policy axis together, there are some more classes and templates.
-
-    <dl>
-    <dt>\c class \c SocketPolicyBase</dt>
-    <dd>This class is the base class of the SocketPolicy template. It
-    is used to validate, that a class is really a SocketPolicy (by
-    checking, that it derives from SocketPolicyBase. This is simpler
-    than chacking the template directly).</dd>
-
-    <dt>\c template \c SocketPolicy < \e addressingPolicy, \e
-    framingPolicy, \e communicationPolicy, \e readPolicy, \e
-    writePolicy, \e bufferingPolicy ></dt>
-    <dd>This is the central SocketPolicy template. It combines a
-    complete set of policy classes, one for each axis.</dd>
-
-    <dt>\c template \c MakeSocketPolicy < \e args ></dt>
-    <dd>\c MakeSocketPolicy is a template metafunction which
-    simplifies building SocketPolicy instantiations. It takes any
-    number (ok, up to a maximum of 6) of policy classes as an
-    argument (in any order). It will sort these arguments into the
-    SocketPolicy template arguments. If for some axis no class is
-    specified, it's slot will be filled with \c Unspecified \e
-    Policy. Additionally, the first Argument may optionally be ab
-    arbitrary SocketPolicy. It will provide default values for
-    unspecified axis</dd>
-
-    <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt>
-    <dd>This template metafunction will check, wether the socket
-    policy \e derived is convertible to \e base. This means, that for
-    each axis, the corresponding policy class in \e derived must be
-    derived or be the same as the one on \e base.</dd>
-    </dl>
-
-    \implementation All these classes are created automatically. The
-    \c SENF_SOCKET_POLICIES makro is a Boost.Preprocessor style
-    sequence listing all policy axis. The Boost.Preprocessor library
+    \li \e Axis is one or \c AddressingPolicy, \c FramingPolicy, \c CommunicationPolicy, \c
+        ReadPolicy, \c WritePolicy or \c BufferingPolicy
+    \li \e socketPolicy is any socket policy (that is, an instantiation of the SocketPolicy
+        template)
+    \li \e trait is an any policy class (that is, any class derived from one of the axis base
+        classes)
+
+    Each axis is comprised of a number of classes and templates (all in namespace senf of course):
+
+    <dl><dt>\e Axis \c Base (ex: AddressingPolicyBase)</dt><dd>Baseclass of all policies in this
+    axis</dd>
+
+    <dt>\c Unspecified \e Axis (ex: \ref UnspecifiedAddressingPolicy)</dt> <dd>An alias (typedef)
+    for \e Axis \c Base</dd>
+
+    <dt>\e Axis \c Is < \e socketPolicy, \e trait > (ex: AddressingPolicyIs)</dt> <dd>A template
+    metafunction returning \c boost::true_type, if \e trait (any class derived from \e Axis \c
+    Base) is a compatible policy value of the given \e socketPolicy</dd>
+
+    <dt>\c If \e Axis \c Is < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIs)</dt> <dd>This
+    is a combination of \e Axis \c Is and \c boost::enable_if</dd>
+
+    <dt>\c If \e Axis \c IsNot < \e socketPolicy, \e trait > (ex: IfAddressingPolicyIsNot)</dt>
+    <dd>The inverse of above</dd> </dl>
+
+    These classes form the basis of the policy framework. To bind the policy axis together, there
+    are some more classes and templates.
+
+    <dl><dt>\c class \c SocketPolicyBase</dt> <dd>This class is the base class of the SocketPolicy
+    template. It is used to validate, that a class is really a SocketPolicy (by checking, that it
+    derives from SocketPolicyBase. This is simpler than chacking the template directly).</dd>
+
+    <dt>\c template \c SocketPolicy < \e addressingPolicy, \e framingPolicy, \e communicationPolicy,
+    \e readPolicy, \e writePolicy, \e bufferingPolicy ></dt> <dd>This is the central SocketPolicy
+    template. It combines a complete set of policy classes, one for each axis.</dd>
+
+    <dt>\c template \c MakeSocketPolicy < \e args ></dt> <dd>\c MakeSocketPolicy is a template
+    metafunction which simplifies building SocketPolicy instantiations. It takes any number (ok, up
+    to a maximum of 6) of policy classes as an argument (in any order). It will sort these arguments
+    into the SocketPolicy template arguments. If for some axis no class is specified, it's slot will
+    be filled with \c Unspecified \e Axis. Additionally, the first Argument may optionally be ab
+    arbitrary SocketPolicy. It will provide default values for unspecified axis</dd>
+
+    <dt>\c template \c SocketPolicyIsBaseOf < \e base, \e derived ></dt> <dd>This template
+    metafunction will check, wether the socket policy \e derived is convertible to \e base. This
+    means, that for each axis, the corresponding policy class in \e derived must be derived or be
+    the same as the one on \e base.</dd> </dl>
+
+    \implementation All these classes are created automatically. The \c SENF_SOCKET_POLICIES makro
+    is a Boost.Preprocessor style sequence listing all policy axis. The Boost.Preprocessor library
     is then used to generate the respective classes.
 
     \section policy_implement Implementing Policy Classes
 
-    To define a new policy class, derive from the corresponding base
-    class for your policy axies. The only policy axis which might
-    possibly need to be extended are the addressing policy
-    (AddressingPolicyBase) and the buffering policy
-    (BufferingPolicyBase). See the Documentation of these classes for
-    more information on which members can be implemented.
-
-    All members you define must be static. For any of the policy
-    classes, you must only define those members which are supported by
-    your implementation. If you leave out a member you automatically
-    disable the corresponding functionality in the
-    ClientSocketHandle/ServerSocketHandle interface.
-
-    The member prototypes given in the base class documentation only
-    specify the call signature not the way, the member must be defined
-    (FileHandle really is not a FileHandle but an arbitrary
+    To define a new policy class, derive from the corresponding base class for your policy
+    axies. The only policy axis which might possibly need to be extended are the addressing policy
+    (AddressingPolicyBase) and the buffering policy (BufferingPolicyBase). See the Documentation of
+    these classes for more information on which members can be implemented.
+
+    All members you define must be static. For any of the policy classes, you must only define those
+    members which are supported by your implementation. If you leave out a member you automatically
+    disable the corresponding functionality in the ClientSocketHandle/ServerSocketHandle interface.
+
+    The member prototypes given in the base class documentation only specify the call signature not
+    the way, the member must be defined (FileHandle really is not a FileHandle but an arbitrary
     SocketHandle).
 
-    If the existence of a member depends on other policies, you should
-    use the <code>If</code><i>SomePolicy</i><code>Is</code> and
-    <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to
-    dynamically enable/disable the member depending on some other
-    policy:
+    If the existence of a member depends on other policies, you should use the
+    <code>If</code><i>SomePolicy</i><code>Is</code> and
+    <code>If</code><i>SomePolicy</i><code>IsNot</code> templates to dynamically enable/disable the
+    member depending on some other policy:
 
     \code
       struct ExampleAddressingPolicy
       };
     \endcode
 
-    The \c connect member in this example will only be enabled, it
-    the communication policy of the socket handle is
-    ConnectedCommunicationPolicy (or a derived type). See <a
-    href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a>
-    for a discussion of the third argument (\c
-    senf::ConnectedCommunicationPolicyIs is based on the \c
-    boost::enable_if template).
+    The \c connect member in this example will only be enabled, it the communication policy of the
+    socket handle is ConnectedCommunicationPolicy (or a derived type). See <a
+    href="http://www.boost.org/libs/utility/enable_if.html">Boost.Enable_If</a> for a discussion of
+    the third argument (\c senf::ConnectedCommunicationPolicyIs is based on the \c boost::enable_if
+    template).
 
     \see \ref extend_policy \n
          <a class="ext" href="http://www.boost.org/libs/utility/enable_if.html">The Boost enable_if utility</a> \n
          <a class="ext" href="http://www.boost.org/libs/mpl/doc/index.html">The Boost.MPL library</a> \n
          <a class="ext" href="http://www.boost.org/libs/preprocessor/doc/index.html">The Boost.Preprocessor library</a>
 
-    \idea We could combine all the \e Policy \c Is templates into a
-    single template. Since the \e trait argument will automatically
-    specify the axis to be used, it is not necessary to specify that
-    axis in the tempalte functor's name. We could even combine this
-    with \c SocketPolicyIsBaseOf.
+    \idea We could combine all the \e Axis \c Is templates into a single template. Since the \e
+    trait argument will automatically specify the axis to be used, it is not necessary to specify
+    that axis in the tempalte functor's name. We could even combine this with \c
+    SocketPolicyIsBaseOf.
  */
 
 /** \defgroup policy_impl_group Policy Implementation classes
@@ -260,9 +254,8 @@ namespace senf {
     /// \addtogroup policy_group
     /// @{
 
-    // This may be adapted to change the supported policies (however,
-    // ClientSocketHandle and ServerSocketHandle will probably have to
-    // be adjusted accordingly)
+    // This may be adapted to change the supported policies (however, ClientSocketHandle and
+    // ServerSocketHandle will probably have to be adjusted accordingly)
 
     /** \brief List all policy axis
 
@@ -448,7 +441,7 @@ namespace senf {
 
     /** \brief Check single policy axis
 
-        This template is an example of the \e Policy \c Is family of
+        This template is an example of the \e Axis \c Is family of
         tempalte metafunctions. It will check, wether \c Trait is a
         valid compatible Policy class of \c SocketPolicy. \c Trait
         must be derived from AddressingPolicyBase (respectively \i
@@ -462,11 +455,11 @@ namespace senf {
 
     /** \brief Enable template overload depending on policy value
 
-        This template is an exmaple of the \c If \e Policy \c Is
+        This template is an exmaple of the \c If \e Axis \c Is
         family of templates. It is used like <a class="ext"
         href="http://www.boost.org/libs/utility/enable_if.html">Boost.enable_if</a>
         to enable a templated overload only, if the AddressingPolicy
-        of \e Policy is compatible with \c Trait (that is the
+        of \e Axis is compatible with \c Trait (that is the
         AddressingPolicy of \c Policy is derived from \c Trait).
 
         \see policy_group
@@ -517,7 +510,7 @@ namespace senf {
 
         A SocketPolicy can be complete or incomplete. An incomplete
         SocketPolicy will have at least one axis set to \c Undefined
-        \e Policy (or a generic derived class which is used to group
+        \e Axis (or a generic derived class which is used to group
         some other policies but does not (completely) define the
         policy behavior). A complete SocketPolicy will have a
         concrete definition of the desired behavior for each policy
@@ -550,7 +543,7 @@ namespace senf {
         SocketPolicy instantiation. It takes any number (that is up to
         6) of Policy classes as arguments in any Order. It will create
         a SocketPolicy from these policy classes. Any axis not
-        specified will be left as \c Unspecified \e Policy.
+        specified will be left as \c Unspecified \e Axis.
 
         \see policy_group
      */
index dc70184..b959702 100644 (file)
@@ -7,7 +7,8 @@ INPUT_FILTER           = "$(TOPDIR)/doclib/filter.pl"
 
 ALIASES                = "fixme=\xrefitem fixme \"Fix\" \"Fixmes\"" \
                          "idea=\xrefitem idea \"Idea\" \"Ideas\"" \
-                         "implementation=\par \"Implementation note:\""
+                         "implementation=\par \"Implementation note:\"" \
+                         "doc=\xrefitem doc \"Documentation request\" \"Documentation Requests\""
 REPEAT_BRIEF           = YES
 ALWAYS_DETAILED_SEC    = YES
 MULTILINE_CPP_IS_BRIEF = YES