This diagram tries to give a structural overview of the Socket Library, it does 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 policy interface and the protocol interface. Together they provide the complete API for a specific type of Socket as defined by the Protocol. The policy interface provides highly efficient access to the most frequently used operations whereas the protocol interface 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.
This complete socket policy 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 incomplete. This mans, that the 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 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 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).
This can be described as generalized compile-time polymorphism: A base class reference to some derived class will only give access to a reduced interface (the base class interface) of a class. The class still is of it's derived type (and inherently has the complete interface) but only part of it is accessible via the base class reference. Likewise a generic handle (aka base class reference) will only provide a reduced interface (aka base class interface) to the derived class instance (aka socket).
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 has a complete policy and it knows the exact protocol type of the socket (which generic handles don't). This allows to access to the complete protocol interface.
The Handle hierarchy divides the interface into two separate strains: the client interface (senf::ClientSocketHandle and senf::ProtocolClientSocketHandle) provides the interface of a client socket whereas the server interface (senf::ServerSocketHandle and senf::ProtocolServerSocketHandle) provides the interface as used by server sockets.
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 The Protocol Classes).