Home | History | Annotate | Download | only in asio
      1 //
      2 // basic_io_object.hpp
      3 // ~~~~~~~~~~~~~~~~~~~
      4 //
      5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
      6 //
      7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
      8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      9 //
     10 
     11 #ifndef ASIO_BASIC_IO_OBJECT_HPP
     12 #define ASIO_BASIC_IO_OBJECT_HPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include "asio/io_service.hpp"
     17 
     18 #include "asio/detail/push_options.hpp"
     19 
     20 namespace asio {
     21 
     22 namespace detail
     23 {
     24   // Type trait used to determine whether a service supports move.
     25   template <typename IoObjectService>
     26   class service_has_move
     27   {
     28   private:
     29     typedef IoObjectService service_type;
     30     typedef typename service_type::implementation_type implementation_type;
     31 
     32     template <typename T, typename U>
     33     static auto eval(T* t, U* u) -> decltype(t->move_construct(*u, *u), char());
     34     static char (&eval(...))[2];
     35 
     36   public:
     37     static const bool value =
     38       sizeof(service_has_move::eval(
     39         static_cast<service_type*>(0),
     40         static_cast<implementation_type*>(0))) == 1;
     41   };
     42 }
     43 
     44 /// Base class for all I/O objects.
     45 /**
     46  * @note All I/O objects are non-copyable. However, when using C++0x, certain
     47  * I/O objects do support move construction and move assignment.
     48  */
     49 template <typename IoObjectService,
     50     bool Movable = detail::service_has_move<IoObjectService>::value>
     51 class basic_io_object
     52 {
     53 public:
     54   /// The type of the service that will be used to provide I/O operations.
     55   typedef IoObjectService service_type;
     56 
     57   /// The underlying implementation type of I/O object.
     58   typedef typename service_type::implementation_type implementation_type;
     59 
     60   /// Get the io_service associated with the object.
     61   /**
     62    * This function may be used to obtain the io_service object that the I/O
     63    * object uses to dispatch handlers for asynchronous operations.
     64    *
     65    * @return A reference to the io_service object that the I/O object will use
     66    * to dispatch handlers. Ownership is not transferred to the caller.
     67    */
     68   asio::io_service& get_io_service()
     69   {
     70     return service.get_io_service();
     71   }
     72 
     73 protected:
     74   /// Construct a basic_io_object.
     75   /**
     76    * Performs:
     77    * @code get_service().construct(get_implementation()); @endcode
     78    */
     79   explicit basic_io_object(asio::io_service& io_service)
     80     : service(asio::use_service<IoObjectService>(io_service))
     81   {
     82     service.construct(implementation);
     83   }
     84 
     85 
     86   /// Protected destructor to prevent deletion through this type.
     87   /**
     88    * Performs:
     89    * @code get_service().destroy(get_implementation()); @endcode
     90    */
     91   ~basic_io_object()
     92   {
     93     service.destroy(implementation);
     94   }
     95 
     96   /// Get the service associated with the I/O object.
     97   service_type& get_service()
     98   {
     99     return service;
    100   }
    101 
    102   /// Get the service associated with the I/O object.
    103   const service_type& get_service() const
    104   {
    105     return service;
    106   }
    107 
    108   /// (Deprecated: Use get_service().) The service associated with the I/O
    109   /// object.
    110   /**
    111    * @note Available only for services that do not support movability.
    112    */
    113   service_type& service;
    114 
    115   /// Get the underlying implementation of the I/O object.
    116   implementation_type& get_implementation()
    117   {
    118     return implementation;
    119   }
    120 
    121   /// Get the underlying implementation of the I/O object.
    122   const implementation_type& get_implementation() const
    123   {
    124     return implementation;
    125   }
    126 
    127   /// (Deprecated: Use get_implementation().) The underlying implementation of
    128   /// the I/O object.
    129   implementation_type implementation;
    130 
    131 private:
    132   basic_io_object(const basic_io_object&);
    133   basic_io_object& operator=(const basic_io_object&);
    134 };
    135 
    136 // Specialisation for movable objects.
    137 template <typename IoObjectService>
    138 class basic_io_object<IoObjectService, true>
    139 {
    140 public:
    141   typedef IoObjectService service_type;
    142   typedef typename service_type::implementation_type implementation_type;
    143 
    144   asio::io_service& get_io_service()
    145   {
    146     return service_->get_io_service();
    147   }
    148 
    149 protected:
    150   explicit basic_io_object(asio::io_service& io_service)
    151     : service_(&asio::use_service<IoObjectService>(io_service))
    152   {
    153     service_->construct(implementation);
    154   }
    155 
    156   basic_io_object(basic_io_object&& other)
    157     : service_(&other.get_service())
    158   {
    159     service_->move_construct(implementation, other.implementation);
    160   }
    161 
    162   ~basic_io_object()
    163   {
    164     service_->destroy(implementation);
    165   }
    166 
    167   basic_io_object& operator=(basic_io_object&& other)
    168   {
    169     service_->move_assign(implementation,
    170         *other.service_, other.implementation);
    171     service_ = other.service_;
    172     return *this;
    173   }
    174 
    175   service_type& get_service()
    176   {
    177     return *service_;
    178   }
    179 
    180   const service_type& get_service() const
    181   {
    182     return *service_;
    183   }
    184 
    185   implementation_type& get_implementation()
    186   {
    187     return implementation;
    188   }
    189 
    190   const implementation_type& get_implementation() const
    191   {
    192     return implementation;
    193   }
    194 
    195   implementation_type implementation;
    196 
    197 private:
    198   basic_io_object(const basic_io_object&);
    199   void operator=(const basic_io_object&);
    200 
    201   IoObjectService* service_;
    202 };
    203 
    204 } // namespace asio
    205 
    206 #include "asio/detail/pop_options.hpp"
    207 
    208 #endif // ASIO_BASIC_IO_OBJECT_HPP
    209