|
Boost : |
From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2005-12-13 06:37:10
Hi Eugene,
--- Eugene Alterman <eugalt_at_[hidden]> wrote:
> I will call this interfaces core_socket and stream_socket
> respectively. You always start with an object of a
> stream_socket class and then obtain a reference to core_socket
> from it.
>
> Let us first start with a design that does not change the
> current interface of stream_socket. Define a new core_socket
> class template, and derive stream_socket from it adding the
> stream functionality. Then we can define lowest_layer_type as
> core_socket. This will solve the stream layering problem since
> having a reference to core_socket of a lower layer would not
> allow performing stream operations on it.
>
> The next step would be to derive stream_socket privately from
> core_socket and provide a public member function returning a
> reference to core_socket. This would deal with any temptation
> to downcast a core_socket reference to stream_socket.
I think I understand what you want now, however I propose a few
modifications, especially to preserve source compatibility with
existing code and keep the common use cases simple.
The core_socket template (don't particularly like the name, will
think about it) could be used as the base for both stream_socket
and datagram socket since they share everything except the
read_some/write_some/send*/receive* functions. E.g.:
template <typename Service>
class core_socket
{
public:
...
typedef core_socket<Service> lowest_layer_type;
lowest_layer_type& lowest_layer() { return *this; }
protected:
service_type& service_;
impl_type impl_;
};
template <typename Service>
class basic_stream_socket
: private core_socket<Service>
{
public:
...
typedef core_socket<Service> lowest_layer_type;
lowest_layer_type& lowest_layer() { return *this; }
};
template <typename Service>
class basic_datagram_socket
: private core_socket<Service>
{
public:
...
typedef core_socket<Service> lowest_layer_type;
lowest_layer_type& lowest_layer() { return *this; }
};
The next_layer_type typedefs and next_layer() functions would
be removed.
The derived type should bring all public names from core_socket
into its own public interface. Are using declarations OK in this
case? If not, then via forwarding functions.
That way existing uses of stream_socket continue to work as-is.
Uses of stream templates would lose access to the underlying
socket's I/O functions, as you want.
Note there is still a way to circumvent the layering but it is
now an explicit choice, e.g.:
stream_socket inner(demuxer);
buffered_stream<stream_socket&> outer(inner);
Would anyone else care to comment on this modification?
Cheers,
Chris
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk