10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// basic_io_object.hpp 30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~~~~ 40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying 80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_BASIC_IO_OBJECT_HPP 120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_BASIC_IO_OBJECT_HPP 130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp" 160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/io_service.hpp" 170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp" 190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio { 210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace detail 230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // Type trait used to determine whether a service supports move. 250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename IoObjectService> 260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie class service_has_move 270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie private: 290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef IoObjectService service_type; 300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename service_type::implementation_type implementation_type; 310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename T, typename U> 330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static auto eval(T* t, U* u) -> decltype(t->move_construct(*u, *u), char()); 340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static char (&eval(...))[2]; 350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie public: 370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static const bool value = 380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie sizeof(service_has_move::eval( 390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_cast<service_type*>(0), 400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie static_cast<implementation_type*>(0))) == 1; 410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie }; 420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} 430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Base class for all I/O objects. 450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/** 460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note All I/O objects are non-copyable. However, when using C++0x, certain 470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * I/O objects do support move construction and move assignment. 480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename IoObjectService, 500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool Movable = detail::service_has_move<IoObjectService>::value> 510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass basic_io_object 520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic: 540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// The type of the service that will be used to provide I/O operations. 550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef IoObjectService service_type; 560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// The underlying implementation type of I/O object. 580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename service_type::implementation_type implementation_type; 590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the io_service associated with the object. 610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function may be used to obtain the io_service object that the I/O 630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * object uses to dispatch handlers for asynchronous operations. 640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return A reference to the io_service object that the I/O object will use 660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * to dispatch handlers. Ownership is not transferred to the caller. 670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service& get_io_service() 690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return service.get_io_service(); 710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprotected: 740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Construct a basic_io_object. 750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Performs: 770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code get_service().construct(get_implementation()); @endcode 780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie explicit basic_io_object(asio::io_service& io_service) 800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : service(asio::use_service<IoObjectService>(io_service)) 810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service.construct(implementation); 830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Protected destructor to prevent deletion through this type. 870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Performs: 890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code get_service().destroy(get_implementation()); @endcode 900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ~basic_io_object() 920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service.destroy(implementation); 940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the service associated with the I/O object. 970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_type& get_service() 980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return service; 1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the service associated with the I/O object. 1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const service_type& get_service() const 1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return service; 1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// (Deprecated: Use get_service().) The service associated with the I/O 1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// object. 1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Available only for services that do not support movability. 1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_type& service; 1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the underlying implementation of the I/O object. 1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie implementation_type& get_implementation() 1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return implementation; 1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the underlying implementation of the I/O object. 1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const implementation_type& get_implementation() const 1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return implementation; 1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// (Deprecated: Use get_implementation().) The underlying implementation of 1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// the I/O object. 1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie implementation_type implementation; 1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate: 1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object(const basic_io_object&); 1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object& operator=(const basic_io_object&); 1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Specialisation for movable objects. 1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename IoObjectService> 1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass basic_io_object<IoObjectService, true> 1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 1400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic: 1410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef IoObjectService service_type; 1420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename service_type::implementation_type implementation_type; 1430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::io_service& get_io_service() 1450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return service_->get_io_service(); 1470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprotected: 1500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie explicit basic_io_object(asio::io_service& io_service) 1510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : service_(&asio::use_service<IoObjectService>(io_service)) 1520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_->construct(implementation); 1540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object(basic_io_object&& other) 1570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : service_(&other.get_service()) 1580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_->move_construct(implementation, other.implementation); 1600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ~basic_io_object() 1630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_->destroy(implementation); 1650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object& operator=(basic_io_object&& other) 1680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_->move_assign(implementation, 1700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie *other.service_, other.implementation); 1710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_ = other.service_; 1720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *this; 1730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie service_type& get_service() 1760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *service_; 1780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const service_type& get_service() const 1810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *service_; 1830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie implementation_type& get_implementation() 1860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return implementation; 1880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const implementation_type& get_implementation() const 1910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return implementation; 1930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie implementation_type implementation; 1960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprivate: 1980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object(const basic_io_object&); 1990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void operator=(const basic_io_object&); 2000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie IoObjectService* service_; 2020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 2030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio 2050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp" 2070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_BASIC_IO_OBJECT_HPP 209