avadapal пре 1 година
родитељ
комит
ba184717e3
100 измењених фајлова са 31906 додато и 0 уклоњено
  1. 933 0
      cpir-read/Cargo.lock
  2. 38 0
      cpir-read/Cargo.toml
  3. 148 0
      cpir-read/README.md
  4. 133 0
      cpir-read/boost/boost/asio/associated_allocator.hpp
  5. 151 0
      cpir-read/boost/boost/asio/associated_executor.hpp
  6. 223 0
      cpir-read/boost/boost/asio/async_result.hpp
  7. 1042 0
      cpir-read/boost/boost/asio/basic_datagram_socket.hpp
  8. 630 0
      cpir-read/boost/boost/asio/basic_deadline_timer.hpp
  9. 292 0
      cpir-read/boost/boost/asio/basic_io_object.hpp
  10. 1032 0
      cpir-read/boost/boost/asio/basic_raw_socket.hpp
  11. 620 0
      cpir-read/boost/boost/asio/basic_seq_packet_socket.hpp
  12. 690 0
      cpir-read/boost/boost/asio/basic_serial_port.hpp
  13. 393 0
      cpir-read/boost/boost/asio/basic_signal_set.hpp
  14. 1759 0
      cpir-read/boost/boost/asio/basic_socket.hpp
  15. 1988 0
      cpir-read/boost/boost/asio/basic_socket_acceptor.hpp
  16. 432 0
      cpir-read/boost/boost/asio/basic_socket_iostream.hpp
  17. 709 0
      cpir-read/boost/boost/asio/basic_socket_streambuf.hpp
  18. 923 0
      cpir-read/boost/boost/asio/basic_stream_socket.hpp
  19. 454 0
      cpir-read/boost/boost/asio/basic_streambuf.hpp
  20. 38 0
      cpir-read/boost/boost/asio/basic_streambuf_fwd.hpp
  21. 707 0
      cpir-read/boost/boost/asio/basic_waitable_timer.hpp
  22. 613 0
      cpir-read/boost/boost/asio/bind_executor.hpp
  23. 2164 0
      cpir-read/boost/boost/asio/buffer.hpp
  24. 259 0
      cpir-read/boost/boost/asio/buffered_read_stream.hpp
  25. 27 0
      cpir-read/boost/boost/asio/buffered_read_stream_fwd.hpp
  26. 280 0
      cpir-read/boost/boost/asio/buffered_stream.hpp
  27. 27 0
      cpir-read/boost/boost/asio/buffered_stream_fwd.hpp
  28. 251 0
      cpir-read/boost/boost/asio/buffered_write_stream.hpp
  29. 27 0
      cpir-read/boost/boost/asio/buffered_write_stream_fwd.hpp
  30. 523 0
      cpir-read/boost/boost/asio/buffers_iterator.hpp
  31. 220 0
      cpir-read/boost/boost/asio/completion_condition.hpp
  32. 1061 0
      cpir-read/boost/boost/asio/connect.hpp
  33. 330 0
      cpir-read/boost/boost/asio/coroutine.hpp
  34. 468 0
      cpir-read/boost/boost/asio/datagram_socket_service.hpp
  35. 40 0
      cpir-read/boost/boost/asio/deadline_timer.hpp
  36. 175 0
      cpir-read/boost/boost/asio/deadline_timer_service.hpp
  37. 109 0
      cpir-read/boost/boost/asio/defer.hpp
  38. 40 0
      cpir-read/boost/boost/asio/detail/array.hpp
  39. 34 0
      cpir-read/boost/boost/asio/detail/array_fwd.hpp
  40. 32 0
      cpir-read/boost/boost/asio/detail/assert.hpp
  41. 47 0
      cpir-read/boost/boost/asio/detail/atomic_count.hpp
  42. 70 0
      cpir-read/boost/boost/asio/detail/base_from_completion_cond.hpp
  43. 818 0
      cpir-read/boost/boost/asio/detail/bind_handler.hpp
  44. 68 0
      cpir-read/boost/boost/asio/detail/buffer_resize_guard.hpp
  45. 546 0
      cpir-read/boost/boost/asio/detail/buffer_sequence_adapter.hpp
  46. 128 0
      cpir-read/boost/boost/asio/detail/buffered_stream_storage.hpp
  47. 127 0
      cpir-read/boost/boost/asio/detail/call_stack.hpp
  48. 68 0
      cpir-read/boost/boost/asio/detail/chrono.hpp
  49. 192 0
      cpir-read/boost/boost/asio/detail/chrono_time_traits.hpp
  50. 85 0
      cpir-read/boost/boost/asio/detail/completion_handler.hpp
  51. 94 0
      cpir-read/boost/boost/asio/detail/concurrency_hint.hpp
  52. 114 0
      cpir-read/boost/boost/asio/detail/conditionally_enabled_event.hpp
  53. 151 0
      cpir-read/boost/boost/asio/detail/conditionally_enabled_mutex.hpp
  54. 1435 0
      cpir-read/boost/boost/asio/detail/config.hpp
  55. 416 0
      cpir-read/boost/boost/asio/detail/consuming_buffers.hpp
  56. 33 0
      cpir-read/boost/boost/asio/detail/cstddef.hpp
  57. 62 0
      cpir-read/boost/boost/asio/detail/cstdint.hpp
  58. 34 0
      cpir-read/boost/boost/asio/detail/date_time_fwd.hpp
  59. 280 0
      cpir-read/boost/boost/asio/detail/deadline_timer_service.hpp
  60. 38 0
      cpir-read/boost/boost/asio/detail/dependent_type.hpp
  61. 123 0
      cpir-read/boost/boost/asio/detail/descriptor_ops.hpp
  62. 130 0
      cpir-read/boost/boost/asio/detail/descriptor_read_op.hpp
  63. 130 0
      cpir-read/boost/boost/asio/detail/descriptor_write_op.hpp
  64. 220 0
      cpir-read/boost/boost/asio/detail/dev_poll_reactor.hpp
  65. 268 0
      cpir-read/boost/boost/asio/detail/epoll_reactor.hpp
  66. 50 0
      cpir-read/boost/boost/asio/detail/event.hpp
  67. 85 0
      cpir-read/boost/boost/asio/detail/eventfd_select_interrupter.hpp
  68. 86 0
      cpir-read/boost/boost/asio/detail/executor_op.hpp
  69. 41 0
      cpir-read/boost/boost/asio/detail/fd_set_adapter.hpp
  70. 82 0
      cpir-read/boost/boost/asio/detail/fenced_block.hpp
  71. 40 0
      cpir-read/boost/boost/asio/detail/functional.hpp
  72. 93 0
      cpir-read/boost/boost/asio/detail/gcc_arm_fenced_block.hpp
  73. 70 0
      cpir-read/boost/boost/asio/detail/gcc_hppa_fenced_block.hpp
  74. 67 0
      cpir-read/boost/boost/asio/detail/gcc_sync_fenced_block.hpp
  75. 101 0
      cpir-read/boost/boost/asio/detail/gcc_x86_fenced_block.hpp
  76. 54 0
      cpir-read/boost/boost/asio/detail/global.hpp
  77. 237 0
      cpir-read/boost/boost/asio/detail/handler_alloc_helpers.hpp
  78. 45 0
      cpir-read/boost/boost/asio/detail/handler_cont_helpers.hpp
  79. 57 0
      cpir-read/boost/boost/asio/detail/handler_invoke_helpers.hpp
  80. 242 0
      cpir-read/boost/boost/asio/detail/handler_tracking.hpp
  81. 558 0
      cpir-read/boost/boost/asio/detail/handler_type_requirements.hpp
  82. 97 0
      cpir-read/boost/boost/asio/detail/handler_work.hpp
  83. 333 0
      cpir-read/boost/boost/asio/detail/hash_map.hpp
  84. 120 0
      cpir-read/boost/boost/asio/detail/impl/buffer_sequence_adapter.ipp
  85. 476 0
      cpir-read/boost/boost/asio/detail/impl/descriptor_ops.ipp
  86. 93 0
      cpir-read/boost/boost/asio/detail/impl/dev_poll_reactor.hpp
  87. 448 0
      cpir-read/boost/boost/asio/detail/impl/dev_poll_reactor.ipp
  88. 91 0
      cpir-read/boost/boost/asio/detail/impl/epoll_reactor.hpp
  89. 789 0
      cpir-read/boost/boost/asio/detail/impl/epoll_reactor.ipp
  90. 167 0
      cpir-read/boost/boost/asio/detail/impl/eventfd_select_interrupter.ipp
  91. 360 0
      cpir-read/boost/boost/asio/detail/impl/handler_tracking.ipp
  92. 95 0
      cpir-read/boost/boost/asio/detail/impl/kqueue_reactor.hpp
  93. 568 0
      cpir-read/boost/boost/asio/detail/impl/kqueue_reactor.ipp
  94. 76 0
      cpir-read/boost/boost/asio/detail/impl/null_event.ipp
  95. 126 0
      cpir-read/boost/boost/asio/detail/impl/pipe_select_interrupter.ipp
  96. 61 0
      cpir-read/boost/boost/asio/detail/impl/posix_event.ipp
  97. 48 0
      cpir-read/boost/boost/asio/detail/impl/posix_mutex.ipp
  98. 86 0
      cpir-read/boost/boost/asio/detail/impl/posix_thread.ipp
  99. 48 0
      cpir-read/boost/boost/asio/detail/impl/posix_tss_ptr.ipp
  100. 224 0
      cpir-read/boost/boost/asio/detail/impl/reactive_descriptor_service.ipp

+ 933 - 0
cpir-read/Cargo.lock

@@ -0,0 +1,933 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aes"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+]
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cc"
+version = "1.0.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
+dependencies = [
+ "iana-time-zone",
+ "num-integer",
+ "num-traits",
+ "serde",
+ "winapi",
+]
+
+[[package]]
+name = "cipher"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "crossbeam-utils",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "curve25519-dalek-ng"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b8dfd4d479156d9ad3fe6d1562f78ff31a9ba8831d3575126061541c7294e48"
+dependencies = [
+ "byteorder",
+ "digest",
+ "packed_simd_2",
+ "rand_core 0.5.1",
+ "serde",
+ "subtle-ng",
+ "zeroize",
+]
+
+[[package]]
+name = "cxx"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
+dependencies = [
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
+dependencies = [
+ "cc",
+ "codespan-reporting",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn",
+]
+
+[[package]]
+name = "cxxbridge-flags"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "darling"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "either"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "generic-array"
+version = "0.14.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "winapi",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "indexmap"
+version = "1.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+ "serde",
+]
+
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.138"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+
+[[package]]
+name = "libm"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
+
+[[package]]
+name = "link-cplusplus"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "packed_simd_2"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282"
+dependencies = [
+ "cfg-if",
+ "libm",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.8",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rayon"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "num_cpus",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "scratch"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
+
+[[package]]
+name = "serde"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_with"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef"
+dependencies = [
+ "base64",
+ "chrono",
+ "hex",
+ "indexmap",
+ "serde",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer",
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "spiral-rs"
+version = "0.1.0"
+source = "git+https://github.com/menonsamir/spiral-rs/?rev=176e396d#176e396d7f46964e5068048db9ecdd274e436de1"
+dependencies = [
+ "getrandom 0.2.8",
+ "rand 0.8.5",
+ "rand_chacha 0.3.1",
+ "rayon",
+ "serde_json",
+]
+
+[[package]]
+name = "spiral-spir"
+version = "0.1.0"
+dependencies = [
+ "aes",
+ "bincode",
+ "curve25519-dalek-ng",
+ "lazy_static",
+ "rand 0.7.3",
+ "rand 0.8.5",
+ "rand_chacha 0.3.1",
+ "rayon",
+ "serde",
+ "serde_with",
+ "sha2",
+ "spiral-rs",
+ "subtle-ng",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "subtle-ng"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142"
+
+[[package]]
+name = "syn"
+version = "1.0.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "time"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+dependencies = [
+ "itoa",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+dependencies = [
+ "time-core",
+]
+
+[[package]]
+name = "typenum"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "zeroize"
+version = "1.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"

+ 38 - 0
cpir-read/Cargo.toml

@@ -0,0 +1,38 @@
+[package]
+name = "spiral-spir"
+version = "0.1.0"
+authors = ["Ian Goldberg <iang@uwaterloo.ca>"]
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+aes = "0.8"
+# curve25519-dalek needs this older version of rand
+rand07 = { package = "rand", version = "0.7" }
+# but Spiral needs this newer version
+rand = "0.8"
+curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
+lazy_static = "1"
+sha2 = "0.9"
+subtle = { package = "subtle-ng", version = "2.4" }
+spiral-rs = { git = "https://github.com/menonsamir/spiral-rs/", rev = "176e396d" }
+rayon = "1.5"
+bincode = "1"
+serde = "1"
+serde_with = "2"
+rand_chacha = "0.3"
+
+[lib]
+crate_type = ["lib", "staticlib"]
+path = "src/lib.rs"
+
+[[bin]]
+name = "spiral-spir"
+path = "src/main.rs"
+
+[features]
+default = ["u64_backend"]
+u32_backend = ["curve25519-dalek/u32_backend"]
+u64_backend = ["curve25519-dalek/u64_backend"]
+simd_backend = ["curve25519-dalek/simd_backend"]

+ 148 - 0
cpir-read/README.md

@@ -0,0 +1,148 @@
+# Symmetric Private Information Retrieval (SPIR) built on Spiral
+
+*Ian Goldberg (iang@uwaterloo.ca), July 2022*
+
+Last update August 2022
+
+This code implements Symmetric Private Information Retrieval, building
+on the Spiral PIR library (this code is not written by the Spiral
+authors).
+
+Spiral is a recent single-server (computational) PIR system from 2022:
+
+  * Samir Jordan Menon, David J. Wu,
+"Spiral: Fast, High-Rate Single-Server PIR via FHE Composition".
+IEEE Symposium on Security and Privacy, 2022.
+eprint:
+[https://eprint.iacr.org/2022/368](https://eprint.iacr.org/2022/368),
+code:
+[https://github.com/menonsamir/spiral-rs](https://github.com/menonsamir/spiral-rs)
+
+In ordinary PIR, the client learns the database record they were looking for, and the server does not learn which record that was.  The client is _not_ prevented, however, from learning _additional_ database records.  Downloading the whole database, for example, can be seen as a trivial form of PIR (though one that transfers way too much data, except for tiny databases).
+
+In Symmetric PIR (SPIR), the client must learn only one database record, in addition to the server learning no information about which record that was.  SPIR is similar to oblivious transfer (OT), except that SPIR aims to have sublinear communication (at no time is something the size of the whole database downloaded), while OT does not have that restriction.
+
+This code builds SPIR from ordinary PIR (using Spiral), using a strategy based on that of Naor and Pinkas:
+
+  * Moni Naor and Benny Pinkas, "Oblivious Transfer and Polynomial Evaluation".
+STOC 1999.  paper: [https://dl.acm.org/doi/10.1145/301250.301312](https://dl.acm.org/doi/10.1145/301250.301312)
+
+The general strategy is this (for a database with N=2^r records):
+
+  1. Server: Encrypt each record of the database with a unique key
+  2. Client: Use 1-of-N OT to retrieve exactly one key
+  3. Client: Privately download the encrypted record and decrypt it with the key retrieved above
+
+In the Naor and Pinkas paper, step 3 was just trivial download of the whole encrypted database, but we use Sprial to privately retrieve the encrypted record of interest.  Note, however, that the client will typically learn additional nearby records as well, which is why we need to encrypt each record separately.
+
+The 1-of-N OT is built from r 1-of-2 OTs in the same manner as in the Naor and Pinkas paper: the server picks r pairs of random keys, and the client chooses one key from each pair, according to the bits of the desired query index value.  Then each database entry is encrypted with the combination of keys associated with its index.
+
+The Naor and Pinkas paper uses this for its encryption, where F is a pseudorandom function (PRF) family:
+
+   Enc[j] = Db[j] XOR F\_{K_1,j1}(j) XOR F\_{K_2,j2}(j) XOR ... XOR F\_{K_r,jr}(j)
+
+where j1,j2,...,jr are the bits of j, as j ranges from 0 to N-1.
+
+We instead use:
+
+   Ktot = K_1,j1 XOR K_2,k2 XOR ... XOR K_r,kr
+
+   Enc[j] = Db[j] XOR F\_{Ktot}(j)
+
+That is, Naor and Pinkas XOR the _outputs_ of the PRF, whereas we XOR the _keys_.  This requires a slightly stronger assumption on the PRF family (for example, that the functions with different keys are independent, even if the keys have some known XOR relation), but we're going to use AES for F, so that should be fine.
+
+For the 1-of-2 OT protocol, we base it on the simple one from the 1989 paper of Bellare and Micali:
+
+  * Mihir Bellare and Silvio Micali, "Non-Interactive Oblivious Transfer and Applications".  CRYPTO 1989.  paper: [https://cseweb.ucsd.edu/~mihir/papers/niot.pdf](https://cseweb.ucsd.edu/~mihir/papers/niot.pdf)
+
+We slightly optimize the protocol in that instead of the client sending both β0 and β1 to the server, and the server checking that their sum (in elliptic curve terms) is C, the client just sends β0 and the server computes β1 = C-β0.  In addition, the server sends back the two keys ElGamal-encrypted to the keys β0 and β1, where the client can know the private key for at most one of them.  Bellare and Micali's paper does this as (s0\*G, H(s0\*β0) XOR K0, s1\*G, H(s1\*β1) XOR K1), whereas we use the slightly more efficient (s\*G, H(s\*β0) XOR K0, H(s\*β1) XOR K1).
+
+## Running the code
+
+In the August 2022 version, this code is now built as a Rust library
+that can be called from Rust or from C++.
+
+To build the Rust library and a Rust test program:
+
+`RUSTFLAGS="-C target-cpu=native" cargo build --release`
+
+To build the C++ library that wraps the Rust library and a C++ test program:
+
+`make -C cxx`
+
+To run the Rust test program:
+
+`./target/release/spiral-spir 20 4 100 2`
+
+To run the C++ test program:
+
+`./cxx/spir_test 20 4 100 2`
+
+Here:
+
+  * `20` is the value of r (that is, the database will have N=2^20 entries)
+  * `4` is the number of threads to use (defaults to 1)
+  * `100` is the number of SPIR queries to prepare in the preprocessing
+    step; there is only one round trip from the client to the server
+    regardless of this number, but the message and response are larger
+    (defaults to 1)
+  * `2` is the number of SPIR queries to do, one at a time. Must be at
+    most the number of preprocessed queries, and defaults to that
+    number
+  
+Each entry is 8 bytes.  There are three phases of execution: a one-time Spiral public key generation (this only has to be done once, regardless of how many SPIR queries you do), a preprocessing phase per SPIR query (this can be done _before_ knowing the contents of the database on the server side, or the desired index on the client side, as as above, the preprocessing for all of the SPIR queries are all done in a single round trip), and the runtime phase per SPIR query (once the contents of the database and the desired index are known).
+
+A sample output (for r=20, 4 threads, 100 preprocessed SPIR queries, 2
+SPIR queries performed):
+
+```
+===== ONE-TIME SETUP =====
+
+One-time setup: 201893 µs
+pub_params len = 10878976
+
+===== PREPROCESSING =====
+
+num_preproc = 100
+Preprocessing client: 76869 µs
+preproc_msg len = 3342408
+Preprocessing server: 53409 µs
+preproc_resp len = 128808
+Preprocessing client finish: 26688 µs
+
+===== SPIR QUERY 1 =====
+
+Query client: 107 µs
+query_msg len = 8
+expansion (took 99798 us).
+Query server: 411422 µs
+query_resp len = 14336
+Query client finish: 832 µs
+idx = 778275; entry = 7783750778395
+
+===== SPIR QUERY 2 =====
+
+Query client: 73 µs
+query_msg len = 8
+expansion (took 90281 us).
+Query server: 406014 µs
+query_resp len = 14336
+Query client finish: 810 µs
+idx = 675158; entry = 6752580675278
+```
+
+The various lines show the amount of wall-clock time taken for various
+parts of the computation and the amount of data transferred between the
+client and the server.  The last line of each SPIR query shows the
+random index that was looked up, and the database value the client
+retrieved.  The value for index i should be (10000001\*(i+100)+20).
+
+## Using the C++ library yourself
+
+Build the C++ library as above:
+
+`make -C cxx`
+
+Then `cxx/spir.hpp` and `cxx/libspir_cxx.a` are the files you'll need.
+\#include the former in your code, and link your program with the latter
+as well as `-lpthread -ldl`.

+ 133 - 0
cpir-read/boost/boost/asio/associated_allocator.hpp

@@ -0,0 +1,133 @@
+//
+// associated_allocator.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
+#define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <memory>
+#include <boost/asio/detail/type_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename>
+struct associated_allocator_check
+{
+  typedef void type;
+};
+
+template <typename T, typename E, typename = void>
+struct associated_allocator_impl
+{
+  typedef E type;
+
+  static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
+  {
+    return e;
+  }
+};
+
+template <typename T, typename E>
+struct associated_allocator_impl<T, E,
+  typename associated_allocator_check<typename T::allocator_type>::type>
+{
+  typedef typename T::allocator_type type;
+
+  static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
+  {
+    return t.get_allocator();
+  }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the allocator associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Allocator shall be a type meeting the Allocator requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c a is an object of type @c
+ * Allocator.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Allocator requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,a) and with return type @c type.
+ */
+template <typename T, typename Allocator = std::allocator<void> >
+struct associated_allocator
+{
+  /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
+  /// Otherwise @c Allocator.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef see_below type;
+#else // defined(GENERATING_DOCUMENTATION)
+  typedef typename detail::associated_allocator_impl<T, Allocator>::type type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// If @c T has a nested type @c allocator_type, returns
+  /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
+  static type get(const T& t,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return detail::associated_allocator_impl<T, Allocator>::get(t, a);
+  }
+};
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_allocator<T>::type
+get_associated_allocator(const T& t) BOOST_ASIO_NOEXCEPT
+{
+  return associated_allocator<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated allocator.
+/**
+ * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
+ */
+template <typename T, typename Allocator>
+inline typename associated_allocator<T, Allocator>::type
+get_associated_allocator(const T& t, const Allocator& a) BOOST_ASIO_NOEXCEPT
+{
+  return associated_allocator<T, Allocator>::get(t, a);
+}
+
+#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Allocator = std::allocator<void> >
+using associated_allocator_t
+  = typename associated_allocator<T, Allocator>::type;
+
+#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP

+ 151 - 0
cpir-read/boost/boost/asio/associated_executor.hpp

@@ -0,0 +1,151 @@
+//
+// associated_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
+#define BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/is_executor.hpp>
+#include <boost/asio/system_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename>
+struct associated_executor_check
+{
+  typedef void type;
+};
+
+template <typename T, typename E, typename = void>
+struct associated_executor_impl
+{
+  typedef E type;
+
+  static type get(const T&, const E& e) BOOST_ASIO_NOEXCEPT
+  {
+    return e;
+  }
+};
+
+template <typename T, typename E>
+struct associated_executor_impl<T, E,
+  typename associated_executor_check<typename T::executor_type>::type>
+{
+  typedef typename T::executor_type type;
+
+  static type get(const T& t, const E&) BOOST_ASIO_NOEXCEPT
+  {
+    return t.get_executor();
+  }
+};
+
+} // namespace detail
+
+/// Traits type used to obtain the executor associated with an object.
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type. The template parameter @c
+ * Executor shall be a type meeting the Executor requirements.
+ *
+ * Specialisations shall meet the following requirements, where @c t is a const
+ * reference to an object of type @c T, and @c e is an object of type @c
+ * Executor.
+ *
+ * @li Provide a nested typedef @c type that identifies a type meeting the
+ * Executor requirements.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t) and with return type @c type.
+ *
+ * @li Provide a noexcept static member function named @c get, callable as @c
+ * get(t,e) and with return type @c type.
+ */
+template <typename T, typename Executor = system_executor>
+struct associated_executor
+{
+  /// If @c T has a nested type @c executor_type, <tt>T::executor_type</tt>.
+  /// Otherwise @c Executor.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef see_below type;
+#else // defined(GENERATING_DOCUMENTATION)
+  typedef typename detail::associated_executor_impl<T, Executor>::type type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// If @c T has a nested type @c executor_type, returns
+  /// <tt>t.get_executor()</tt>. Otherwise returns @c ex.
+  static type get(const T& t,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return detail::associated_executor_impl<T, Executor>::get(t, ex);
+  }
+};
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T>::get(t)</tt>
+ */
+template <typename T>
+inline typename associated_executor<T>::type
+get_associated_executor(const T& t) BOOST_ASIO_NOEXCEPT
+{
+  return associated_executor<T>::get(t);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, Executor>::get(t, ex)</tt>
+ */
+template <typename T, typename Executor>
+inline typename associated_executor<T, Executor>::type
+get_associated_executor(const T& t, const Executor& ex,
+    typename enable_if<is_executor<
+      Executor>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
+{
+  return associated_executor<T, Executor>::get(t, ex);
+}
+
+/// Helper function to obtain an object's associated executor.
+/**
+ * @returns <tt>associated_executor<T, typename
+ * ExecutionContext::executor_type>::get(t, ctx.get_executor())</tt>
+ */
+template <typename T, typename ExecutionContext>
+inline typename associated_executor<T,
+  typename ExecutionContext::executor_type>::type
+get_associated_executor(const T& t, ExecutionContext& ctx,
+    typename enable_if<is_convertible<ExecutionContext&,
+      execution_context&>::value>::type* = 0) BOOST_ASIO_NOEXCEPT
+{
+  return associated_executor<T,
+    typename ExecutionContext::executor_type>::get(t, ctx.get_executor());
+}
+
+#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T, typename Executor = system_executor>
+using associated_executor_t = typename associated_executor<T, Executor>::type;
+
+#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_ASSOCIATED_EXECUTOR_HPP

+ 223 - 0
cpir-read/boost/boost/asio/async_result.hpp

@@ -0,0 +1,223 @@
+//
+// async_result.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_ASYNC_RESULT_HPP
+#define BOOST_ASIO_ASYNC_RESULT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/handler_type.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// An interface for customising the behaviour of an initiating function.
+/**
+ * The async_result traits class is used for determining:
+ *
+ * @li the concrete completion handler type to be called at the end of the
+ * asynchronous operation;
+ *
+ * @li the initiating function return type; and
+ *
+ * @li how the return value of the initiating function is obtained.
+ *
+ * The trait allows the handler and return types to be determined at the point
+ * where the specific completion handler signature is known.
+ *
+ * This template may be specialised for user-defined completion token types.
+ * The primary template assumes that the CompletionToken is the completion
+ * handler.
+ */
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+template <typename CompletionToken, typename Signature>
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+template <typename CompletionToken, typename Signature = void>
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+class async_result
+{
+public:
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  /// The concrete completion handler type for the specific signature.
+  typedef CompletionToken completion_handler_type;
+
+  /// The return type of the initiating function.
+  typedef void return_type;
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  // For backward compatibility, determine the concrete completion handler type
+  // by using the legacy handler_type trait.
+  typedef typename handler_type<CompletionToken, Signature>::type
+    completion_handler_type;
+
+  // For backward compatibility, determine the initiating function return type
+  // using the legacy single-parameter version of async_result.
+  typedef typename async_result<completion_handler_type>::type return_type;
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+
+  /// Construct an async result from a given handler.
+  /**
+   * When using a specalised async_result, the constructor has an opportunity
+   * to initialise some state associated with the completion handler, which is
+   * then returned from the initiating function.
+   */
+  explicit async_result(completion_handler_type& h)
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    // No data members to initialise.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    : legacy_result_(h)
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  {
+    (void)h;
+  }
+
+  /// Obtain the value to be returned from the initiating function.
+  return_type get()
+  {
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    // Nothing to do.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    return legacy_result_.get();
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  }
+
+private:
+  async_result(const async_result&) BOOST_ASIO_DELETED;
+  async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
+
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  // No data members.
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+  async_result<completion_handler_type> legacy_result_;
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// (Deprecated: Use two-parameter version of async_result.) An interface for
+/// customising the behaviour of an initiating function.
+/**
+ * This template may be specialised for user-defined handler types.
+ */
+template <typename Handler>
+class async_result<Handler>
+{
+public:
+  /// The return type of the initiating function.
+  typedef void type;
+
+  /// Construct an async result from a given handler.
+  /**
+   * When using a specalised async_result, the constructor has an opportunity
+   * to initialise some state associated with the handler, which is then
+   * returned from the initiating function.
+   */
+  explicit async_result(Handler&)
+  {
+  }
+
+  /// Obtain the value to be returned from the initiating function.
+  type get()
+  {
+  }
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Helper template to deduce the handler type from a CompletionToken, capture
+/// a local copy of the handler, and then create an async_result for the
+/// handler.
+template <typename CompletionToken, typename Signature>
+struct async_completion
+{
+  /// The real handler type to be used for the asynchronous operation.
+  typedef typename boost::asio::async_result<
+    typename decay<CompletionToken>::type,
+      Signature>::completion_handler_type completion_handler_type;
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Constructor.
+  /**
+   * The constructor creates the concrete completion handler and makes the link
+   * between the handler and the asynchronous result.
+   */
+  explicit async_completion(CompletionToken& token)
+    : completion_handler(static_cast<typename conditional<
+        is_same<CompletionToken, completion_handler_type>::value,
+        completion_handler_type&, CompletionToken&&>::type>(token)),
+      result(completion_handler)
+  {
+  }
+#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  explicit async_completion(typename decay<CompletionToken>::type& token)
+    : completion_handler(token),
+      result(completion_handler)
+  {
+  }
+
+  explicit async_completion(const typename decay<CompletionToken>::type& token)
+    : completion_handler(token),
+      result(completion_handler)
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// A copy of, or reference to, a real handler object.
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  typename conditional<
+    is_same<CompletionToken, completion_handler_type>::value,
+    completion_handler_type&, completion_handler_type>::type completion_handler;
+#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  completion_handler_type completion_handler;
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// The result of the asynchronous operation's initiating function.
+  async_result<typename decay<CompletionToken>::type, Signature> result;
+};
+
+namespace detail {
+
+template <typename CompletionToken, typename Signature>
+struct async_result_helper
+  : async_result<typename decay<CompletionToken>::type, Signature>
+{
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  void_or_deduced
+#elif defined(_MSC_VER) && (_MSC_VER < 1500)
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  typename ::boost::asio::detail::async_result_helper< \
+    ct, sig>::return_type
+#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
+  typename ::boost::asio::detail::async_result_helper< \
+    ct, sig>::completion_handler_type
+#else
+# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
+  typename ::boost::asio::async_result< \
+    typename ::boost::asio::decay<ct>::type, sig>::return_type
+#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \
+  typename ::boost::asio::async_result< \
+    typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
+#endif
+
+#endif // BOOST_ASIO_ASYNC_RESULT_HPP

+ 1042 - 0
cpir-read/boost/boost/asio/basic_datagram_socket.hpp

@@ -0,0 +1,1042 @@
+//
+// basic_datagram_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP
+#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/datagram_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides datagram-oriented socket functionality.
+/**
+ * The basic_datagram_socket class template provides asynchronous and blocking
+ * datagram-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
+class basic_datagram_socket
+  : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+{
+public:
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<
+    Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_datagram_socket without opening it.
+  /**
+   * This constructor creates a datagram socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param io_context The io_context object that the datagram socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   */
+  explicit basic_datagram_socket(boost::asio::io_context& io_context)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_datagram_socket.
+  /**
+   * This constructor creates and opens a datagram socket.
+   *
+   * @param io_context The io_context object that the datagram socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_datagram_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+  {
+  }
+
+  /// Construct a basic_datagram_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a datagram socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param io_context The io_context object that the datagram socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the datagram
+   * socket will be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_datagram_socket(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+  {
+  }
+
+  /// Construct a basic_datagram_socket on an existing native socket.
+  /**
+   * This constructor creates a datagram socket object to hold an existing
+   * native socket.
+   *
+   * @param io_context The io_context object that the datagram socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_datagram_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+        io_context, protocol, native_socket)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_datagram_socket from another.
+  /**
+   * This constructor moves a datagram socket from one object to another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_context&) constructor.
+   */
+  basic_datagram_socket(basic_datagram_socket&& other)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_datagram_socket from another.
+  /**
+   * This assignment operator moves a datagram socket from one object to
+   * another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_context&) constructor.
+   */
+  basic_datagram_socket& operator=(basic_datagram_socket&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a datagram socket from one object to another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_datagram_socket(
+      basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_datagram_socket from a socket of another protocol
+  /// type.
+  /**
+   * This assignment operator moves a datagram socket from one object to
+   * another.
+   *
+   * @param other The other basic_datagram_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_datagram_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_datagram_socket>::type& operator=(
+        basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the socket.
+  /**
+   * This function destroys the socket, cancelling any outstanding asynchronous
+   * operations associated with the socket as if by calling @c cancel.
+   */
+  ~basic_datagram_socket()
+  {
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the datagram socket. The function
+   * call will block until the data has been sent successfully or an error
+   * occurs.
+   *
+   * @param buffers One ore more data buffers to be sent on the socket.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected datagram socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code socket.send(boost::asio::buffer(data, size)); @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the datagram socket. The function
+   * call will block until the data has been sent successfully or an error
+   * occurs.
+   *
+   * @param buffers One ore more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected datagram socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the datagram socket. The function
+   * call will block until the data has been sent successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected datagram socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to asynchronously send data on the datagram socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected datagram
+   * socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to asynchronously send data on the datagram socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected datagram
+   * socket.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Send a datagram to the specified endpoint.
+  /**
+   * This function is used to send a datagram to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * boost::asio::ip::udp::endpoint destination(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.send_to(boost::asio::buffer(data, size), destination);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send_to(
+        this->get_implementation(), buffers, destination, 0, ec);
+    boost::asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send a datagram to the specified endpoint.
+  /**
+   * This function is used to send a datagram to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send_to(
+        this->get_implementation(), buffers, destination, flags, ec);
+    boost::asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send a datagram to the specified endpoint.
+  /**
+   * This function is used to send a datagram to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().send_to(this->get_implementation(),
+        buffers, destination, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send a datagram to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * boost::asio::ip::udp::endpoint destination(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.async_send_to(
+   *     boost::asio::buffer(data, size), destination, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, 0,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, 0,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send a datagram to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, flags,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the datagram socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected datagram
+   * socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.receive(boost::asio::buffer(data, size)); @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the datagram socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected datagram
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the datagram socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected datagram
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the datagram
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * datagram socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the datagram
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * datagram socket.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive a datagram with the endpoint of the sender.
+  /**
+   * This function is used to receive a datagram. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * boost::asio::ip::udp::endpoint sender_endpoint;
+   * socket.receive_from(
+   *     boost::asio::buffer(data, size), sender_endpoint);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0, ec);
+    boost::asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive a datagram with the endpoint of the sender.
+  /**
+   * This function is used to receive a datagram. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags, ec);
+    boost::asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive a datagram with the endpoint of the sender.
+  /**
+   * This function is used to receive a datagram. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().receive_from(this->get_implementation(),
+        buffers, sender_endpoint, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive a datagram. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.async_receive_from(
+   *     boost::asio::buffer(data, size), sender_endpoint, handler); @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive a datagram. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the datagram. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP

+ 630 - 0
cpir-read/boost/boost/asio/basic_deadline_timer.hpp

@@ -0,0 +1,630 @@
+//
+// basic_deadline_timer.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP
+#define BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  || defined(GENERATING_DOCUMENTATION)
+
+#include <cstddef>
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/time_traits.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/deadline_timer_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/deadline_timer_service.hpp>
+# define BOOST_ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides waitable timer functionality.
+/**
+ * The basic_deadline_timer class template provides the ability to perform a
+ * blocking or asynchronous wait for a timer to expire.
+ *
+ * A deadline timer is always in one of two states: "expired" or "not expired".
+ * If the wait() or async_wait() function is called on an expired timer, the
+ * wait operation will complete immediately.
+ *
+ * Most applications will use the boost::asio::deadline_timer typedef.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Examples
+ * Performing a blocking wait:
+ * @code
+ * // Construct a timer without setting an expiry time.
+ * boost::asio::deadline_timer timer(io_context);
+ *
+ * // Set an expiry time relative to now.
+ * timer.expires_from_now(boost::posix_time::seconds(5));
+ *
+ * // Wait for the timer to expire.
+ * timer.wait();
+ * @endcode
+ *
+ * @par 
+ * Performing an asynchronous wait:
+ * @code
+ * void handler(const boost::system::error_code& error)
+ * {
+ *   if (!error)
+ *   {
+ *     // Timer expired.
+ *   }
+ * }
+ *
+ * ...
+ *
+ * // Construct a timer with an absolute expiry time.
+ * boost::asio::deadline_timer timer(io_context,
+ *     boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
+ *
+ * // Start an asynchronous wait.
+ * timer.async_wait(handler);
+ * @endcode
+ *
+ * @par Changing an active deadline_timer's expiry time
+ *
+ * Changing the expiry time of a timer while there are pending asynchronous
+ * waits causes those wait operations to be cancelled. To ensure that the action
+ * associated with the timer is performed only once, use something like this:
+ * used:
+ *
+ * @code
+ * void on_some_event()
+ * {
+ *   if (my_timer.expires_from_now(seconds(5)) > 0)
+ *   {
+ *     // We managed to cancel the timer. Start new asynchronous wait.
+ *     my_timer.async_wait(on_timeout);
+ *   }
+ *   else
+ *   {
+ *     // Too late, timer has already expired!
+ *   }
+ * }
+ *
+ * void on_timeout(const boost::system::error_code& e)
+ * {
+ *   if (e != boost::asio::error::operation_aborted)
+ *   {
+ *     // Timer was not cancelled, take necessary action.
+ *   }
+ * }
+ * @endcode
+ *
+ * @li The boost::asio::basic_deadline_timer::expires_from_now() function
+ * cancels any pending asynchronous waits, and returns the number of
+ * asynchronous waits that were cancelled. If it returns 0 then you were too
+ * late and the wait handler has already been executed, or will soon be
+ * executed. If it returns 1 then the wait handler was successfully cancelled.
+ *
+ * @li If a wait handler is cancelled, the boost::system::error_code passed to
+ * it contains the value boost::asio::error::operation_aborted.
+ */
+template <typename Time,
+    typename TimeTraits = boost::asio::time_traits<Time>
+    BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)>
+class basic_deadline_timer
+  : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef io_context::executor_type executor_type;
+
+  /// The time traits type.
+  typedef TimeTraits traits_type;
+
+  /// The time type.
+  typedef typename traits_type::time_type time_type;
+
+  /// The duration type.
+  typedef typename traits_type::duration_type duration_type;
+
+  /// Constructor.
+  /**
+   * This constructor creates a timer without setting an expiry time. The
+   * expires_at() or expires_from_now() functions must be called to set an
+   * expiry time before the timer can be waited on.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   */
+  explicit basic_deadline_timer(boost::asio::io_context& io_context)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+  }
+
+  /// Constructor to set a particular expiry time as an absolute time.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, expressed
+   * as an absolute time.
+   */
+  basic_deadline_timer(boost::asio::io_context& io_context,
+      const time_type& expiry_time)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_at");
+  }
+
+  /// Constructor to set a particular expiry time relative to now.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, relative to
+   * now.
+   */
+  basic_deadline_timer(boost::asio::io_context& io_context,
+      const duration_type& expiry_time)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_from_now");
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_deadline_timer from another.
+  /**
+   * This constructor moves a timer from one object to another.
+   *
+   * @param other The other basic_deadline_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_deadline_timer(io_context&) constructor.
+   */
+  basic_deadline_timer(basic_deadline_timer&& other)
+    : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_deadline_timer from another.
+  /**
+   * This assignment operator moves a timer from one object to another. Cancels
+   * any outstanding asynchronous operations associated with the target object.
+   *
+   * @param other The other basic_deadline_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_deadline_timer(io_context&) constructor.
+   */
+  basic_deadline_timer& operator=(basic_deadline_timer&& other)
+  {
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the timer.
+  /**
+   * This function destroys the timer, cancelling any outstanding asynchronous
+   * wait operations associated with the timer as if by calling @c cancel.
+   */
+  ~basic_deadline_timer()
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_context()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_service()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+  }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+  /// Cancel any asynchronous operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel()
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+    return s;
+  }
+
+  /// Cancel any asynchronous operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel(boost::system::error_code& ec)
+  {
+    return this->get_service().cancel(this->get_implementation(), ec);
+  }
+
+  /// Cancels one asynchronous operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one()
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().cancel_one(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel_one");
+    return s;
+  }
+
+  /// Cancels one asynchronous operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one(boost::system::error_code& ec)
+  {
+    return this->get_service().cancel_one(this->get_implementation(), ec);
+  }
+
+  /// Get the timer's expiry time as an absolute time.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  time_type expires_at() const
+  {
+    return this->get_service().expires_at(this->get_implementation());
+  }
+
+  /// Set the timer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_type& expiry_time)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_at");
+    return s;
+  }
+
+  /// Set the timer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_type& expiry_time,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
+  }
+
+  /// Get the timer's expiry time relative to now.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  duration_type expires_from_now() const
+  {
+    return this->get_service().expires_from_now(this->get_implementation());
+  }
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration_type& expiry_time)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_from_now");
+    return s;
+  }
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration_type& expiry_time,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
+  }
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void wait()
+  {
+    boost::system::error_code ec;
+    this->get_service().wait(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "wait");
+  }
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  void wait(boost::system::error_code& ec)
+  {
+    this->get_service().wait(this->get_implementation(), ec);
+  }
+
+  /// Start an asynchronous wait on the timer.
+  /**
+   * This function may be used to initiate an asynchronous wait against the
+   * timer. It always returns immediately.
+   *
+   * For each call to async_wait(), the supplied handler will be called exactly
+   * once. The handler will be called when:
+   *
+   * @li The timer has expired.
+   *
+   * @li The timer was cancelled, in which case the handler is passed the error
+   * code boost::asio::error::operation_aborted.
+   *
+   * @param handler The handler to be called when the timer expires. Copies
+   * will be made of the handler as required. The function signature of the
+   * handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WaitHandler.
+    BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_wait(this->get_implementation(),
+        BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_wait(this->get_implementation(),
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP

+ 292 - 0
cpir-read/boost/boost/asio/basic_io_object.hpp

@@ -0,0 +1,292 @@
+//
+// basic_io_object.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_IO_OBJECT_HPP
+#define BOOST_ASIO_BASIC_IO_OBJECT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+namespace detail
+{
+  // Type trait used to determine whether a service supports move.
+  template <typename IoObjectService>
+  class service_has_move
+  {
+  private:
+    typedef IoObjectService service_type;
+    typedef typename service_type::implementation_type implementation_type;
+
+    template <typename T, typename U>
+    static auto asio_service_has_move_eval(T* t, U* u)
+      -> decltype(t->move_construct(*u, *u), char());
+    static char (&asio_service_has_move_eval(...))[2];
+
+  public:
+    static const bool value =
+      sizeof(asio_service_has_move_eval(
+        static_cast<service_type*>(0),
+        static_cast<implementation_type*>(0))) == 1;
+  };
+}
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+/// Base class for all I/O objects.
+/**
+ * @note All I/O objects are non-copyable. However, when using C++0x, certain
+ * I/O objects do support move construction and move assignment.
+ */
+#if !defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+template <typename IoObjectService>
+#else
+template <typename IoObjectService,
+    bool Movable = detail::service_has_move<IoObjectService>::value>
+#endif
+class basic_io_object
+{
+public:
+  /// The type of the service that will be used to provide I/O operations.
+  typedef IoObjectService service_type;
+
+  /// The underlying implementation type of I/O object.
+  typedef typename service_type::implementation_type implementation_type;
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_context()
+  {
+    return service_.get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_service()
+  {
+    return service_.get_io_context();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// The type of the executor associated with the object.
+  typedef boost::asio::io_context::executor_type executor_type;
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return service_.get_io_context().get_executor();
+  }
+
+protected:
+  /// Construct a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().construct(get_implementation()); @endcode
+   */
+  explicit basic_io_object(boost::asio::io_context& io_context)
+    : service_(boost::asio::use_service<IoObjectService>(io_context))
+  {
+    service_.construct(implementation_);
+  }
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().move_construct(
+   *     get_implementation(), other.get_implementation()); @endcode
+   *
+   * @note Available only for services that support movability,
+   */
+  basic_io_object(basic_io_object&& other);
+
+  /// Move-assign a basic_io_object.
+  /**
+   * Performs:
+   * @code get_service().move_assign(get_implementation(),
+   *     other.get_service(), other.get_implementation()); @endcode
+   *
+   * @note Available only for services that support movability,
+   */
+  basic_io_object& operator=(basic_io_object&& other);
+
+  /// Perform a converting move-construction of a basic_io_object.
+  template <typename IoObjectService1>
+  basic_io_object(IoObjectService1& other_service,
+      typename IoObjectService1::implementation_type& other_implementation);
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// Protected destructor to prevent deletion through this type.
+  /**
+   * Performs:
+   * @code get_service().destroy(get_implementation()); @endcode
+   */
+  ~basic_io_object()
+  {
+    service_.destroy(implementation_);
+  }
+
+  /// Get the service associated with the I/O object.
+  service_type& get_service()
+  {
+    return service_;
+  }
+
+  /// Get the service associated with the I/O object.
+  const service_type& get_service() const
+  {
+    return service_;
+  }
+
+  /// Get the underlying implementation of the I/O object.
+  implementation_type& get_implementation()
+  {
+    return implementation_;
+  }
+
+  /// Get the underlying implementation of the I/O object.
+  const implementation_type& get_implementation() const
+  {
+    return implementation_;
+  }
+
+private:
+  basic_io_object(const basic_io_object&);
+  basic_io_object& operator=(const basic_io_object&);
+
+  // The service associated with the I/O object.
+  service_type& service_;
+
+  /// The underlying implementation of the I/O object.
+  implementation_type implementation_;
+};
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+// Specialisation for movable objects.
+template <typename IoObjectService>
+class basic_io_object<IoObjectService, true>
+{
+public:
+  typedef IoObjectService service_type;
+  typedef typename service_type::implementation_type implementation_type;
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  boost::asio::io_context& get_io_context()
+  {
+    return service_->get_io_context();
+  }
+
+  boost::asio::io_context& get_io_service()
+  {
+    return service_->get_io_context();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  typedef boost::asio::io_context::executor_type executor_type;
+
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return service_->get_io_context().get_executor();
+  }
+
+protected:
+  explicit basic_io_object(boost::asio::io_context& io_context)
+    : service_(&boost::asio::use_service<IoObjectService>(io_context))
+  {
+    service_->construct(implementation_);
+  }
+
+  basic_io_object(basic_io_object&& other)
+    : service_(&other.get_service())
+  {
+    service_->move_construct(implementation_, other.implementation_);
+  }
+
+  template <typename IoObjectService1>
+  basic_io_object(IoObjectService1& other_service,
+      typename IoObjectService1::implementation_type& other_implementation)
+    : service_(&boost::asio::use_service<IoObjectService>(
+          other_service.get_io_context()))
+  {
+    service_->converting_move_construct(implementation_,
+        other_service, other_implementation);
+  }
+
+  ~basic_io_object()
+  {
+    service_->destroy(implementation_);
+  }
+
+  basic_io_object& operator=(basic_io_object&& other)
+  {
+    service_->move_assign(implementation_,
+        *other.service_, other.implementation_);
+    service_ = other.service_;
+    return *this;
+  }
+
+  service_type& get_service()
+  {
+    return *service_;
+  }
+
+  const service_type& get_service() const
+  {
+    return *service_;
+  }
+
+  implementation_type& get_implementation()
+  {
+    return implementation_;
+  }
+
+  const implementation_type& get_implementation() const
+  {
+    return implementation_;
+  }
+
+private:
+  basic_io_object(const basic_io_object&);
+  void operator=(const basic_io_object&);
+
+  IoObjectService* service_;
+  implementation_type implementation_;
+};
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_IO_OBJECT_HPP

+ 1032 - 0
cpir-read/boost/boost/asio/basic_raw_socket.hpp

@@ -0,0 +1,1032 @@
+//
+// basic_raw_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_RAW_SOCKET_HPP
+#define BOOST_ASIO_BASIC_RAW_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/raw_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides raw-oriented socket functionality.
+/**
+ * The basic_raw_socket class template provides asynchronous and blocking
+ * raw-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
+class basic_raw_socket
+  : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+{
+public:
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<
+    Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_raw_socket without opening it.
+  /**
+   * This constructor creates a raw socket without opening it. The open()
+   * function must be called before data can be sent or received on the socket.
+   *
+   * @param io_context The io_context object that the raw socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   */
+  explicit basic_raw_socket(boost::asio::io_context& io_context)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_raw_socket.
+  /**
+   * This constructor creates and opens a raw socket.
+   *
+   * @param io_context The io_context object that the raw socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_raw_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+  {
+  }
+
+  /// Construct a basic_raw_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a raw socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param io_context The io_context object that the raw socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the raw
+   * socket will be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_raw_socket(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+  {
+  }
+
+  /// Construct a basic_raw_socket on an existing native socket.
+  /**
+   * This constructor creates a raw socket object to hold an existing
+   * native socket.
+   *
+   * @param io_context The io_context object that the raw socket will use
+   * to dispatch handlers for any asynchronous operations performed on the
+   * socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_raw_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+        io_context, protocol, native_socket)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_raw_socket from another.
+  /**
+   * This constructor moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_context&) constructor.
+   */
+  basic_raw_socket(basic_raw_socket&& other)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_raw_socket from another.
+  /**
+   * This assignment operator moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_context&) constructor.
+   */
+  basic_raw_socket& operator=(basic_raw_socket&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_raw_socket from a socket of another protocol type.
+  /**
+   * This constructor moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_raw_socket(basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_raw_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a raw socket from one object to another.
+   *
+   * @param other The other basic_raw_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_raw_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_raw_socket>::type& operator=(
+        basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the socket.
+  /**
+   * This function destroys the socket, cancelling any outstanding asynchronous
+   * operations associated with the socket as if by calling @c cancel.
+   */
+  ~basic_raw_socket()
+  {
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw socket. The function call
+   * will block until the data has been sent successfully or an error occurs.
+   *
+   * @param buffers One ore more data buffers to be sent on the socket.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected raw socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code socket.send(boost::asio::buffer(data, size)); @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw socket. The function call
+   * will block until the data has been sent successfully or an error occurs.
+   *
+   * @param buffers One ore more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected raw socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on a connected socket.
+  /**
+   * This function is used to send data on the raw socket. The function call
+   * will block until the data has been sent successfully or an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @note The send operation can only be used with a connected socket. Use
+   * the send_to function to send data on an unconnected raw socket.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to send data on the raw socket. The function call
+   * will block until the data has been sent successfully or an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected raw
+   * socket.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous send on a connected socket.
+  /**
+   * This function is used to send data on the raw socket. The function call
+   * will block until the data has been sent successfully or an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_send operation can only be used with a connected socket.
+   * Use the async_send_to function to send data on an unconnected raw
+   * socket.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * boost::asio::ip::udp::endpoint destination(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.send_to(boost::asio::buffer(data, size), destination);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send_to(
+        this->get_implementation(), buffers, destination, 0, ec);
+    boost::asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send_to(
+        this->get_implementation(), buffers, destination, flags, ec);
+    boost::asio::detail::throw_error(ec, "send_to");
+    return s;
+  }
+
+  /// Send raw data to the specified endpoint.
+  /**
+   * This function is used to send raw data to the specified remote endpoint.
+   * The function call will block until the data has been sent successfully or
+   * an error occurs.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().send_to(this->get_implementation(),
+        buffers, destination, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send raw data to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * boost::asio::ip::udp::endpoint destination(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.async_send_to(
+   *     boost::asio::buffer(data, size), destination, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send_to(this->get_implementation(),
+        buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send_to(this->get_implementation(),
+        buffers, destination, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send raw data to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent to the remote endpoint.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param destination The remote endpoint to which the data will be sent.
+   * Copies will be made of the endpoint as required.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send_to(const ConstBufferSequence& buffers,
+      const endpoint_type& destination, socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, flags,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send_to(
+        this->get_implementation(), buffers, destination, flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected raw
+   * socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.receive(boost::asio::buffer(data, size)); @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected raw
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the raw socket. The function
+   * call will block until data has been received successfully or an error
+   * occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received.
+   *
+   * @note The receive operation can only be used with a connected socket. Use
+   * the receive_from function to receive data on an unconnected raw
+   * socket.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the raw
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * raw socket.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive on a connected socket.
+  /**
+   * This function is used to asynchronously receive data from the raw
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The async_receive operation can only be used with a connected socket.
+   * Use the async_receive_from function to receive data on an unconnected
+   * raw socket.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the data.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * boost::asio::ip::udp::endpoint sender_endpoint;
+   * socket.receive_from(
+   *     boost::asio::buffer(data, size), sender_endpoint);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0, ec);
+    boost::asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the data.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags, ec);
+    boost::asio::detail::throw_error(ec, "receive_from");
+    return s;
+  }
+  
+  /// Receive raw data with the endpoint of the sender.
+  /**
+   * This function is used to receive raw data. The function call will block
+   * until data has been received successfully or an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the data.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().receive_from(this->get_implementation(),
+        buffers, sender_endpoint, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive raw data. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the data. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code socket.async_receive_from(
+   *     boost::asio::buffer(data, size), 0, sender_endpoint, handler); @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, 0,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive raw data. The function
+   * call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param sender_endpoint An endpoint object that receives the endpoint of
+   * the remote sender of the data. Ownership of the sender_endpoint object
+   * is retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive_from(const MutableBufferSequence& buffers,
+      endpoint_type& sender_endpoint, socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_from(
+        this->get_implementation(), buffers, sender_endpoint, flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_RAW_SOCKET_HPP

+ 620 - 0
cpir-read/boost/boost/asio/basic_seq_packet_socket.hpp

@@ -0,0 +1,620 @@
+//
+// basic_seq_packet_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
+#define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/seq_packet_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides sequenced packet socket functionality.
+/**
+ * The basic_seq_packet_socket class template provides asynchronous and blocking
+ * sequenced packet socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
+class basic_seq_packet_socket
+  : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+{
+public:
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<
+    Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_seq_packet_socket without opening it.
+  /**
+   * This constructor creates a sequenced packet socket without opening it. The
+   * socket needs to be opened and then connected or accepted before data can
+   * be sent or received on it.
+   *
+   * @param io_context The io_context object that the sequenced packet socket
+   * will use to dispatch handlers for any asynchronous operations performed on
+   * the socket.
+   */
+  explicit basic_seq_packet_socket(boost::asio::io_context& io_context)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_seq_packet_socket.
+  /**
+   * This constructor creates and opens a sequenced_packet socket. The socket
+   * needs to be connected or accepted before data can be sent or received on
+   * it.
+   *
+   * @param io_context The io_context object that the sequenced packet socket
+   * will use to dispatch handlers for any asynchronous operations performed on
+   * the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_seq_packet_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+  {
+  }
+
+  /// Construct a basic_seq_packet_socket, opening it and binding it to the
+  /// given local endpoint.
+  /**
+   * This constructor creates a sequenced packet socket and automatically opens
+   * it bound to the specified endpoint on the local machine. The protocol used
+   * is the protocol associated with the given endpoint.
+   *
+   * @param io_context The io_context object that the sequenced packet socket
+   * will use to dispatch handlers for any asynchronous operations performed on
+   * the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the sequenced
+   * packet socket will be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_seq_packet_socket(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+  {
+  }
+
+  /// Construct a basic_seq_packet_socket on an existing native socket.
+  /**
+   * This constructor creates a sequenced packet socket object to hold an
+   * existing native socket.
+   *
+   * @param io_context The io_context object that the sequenced packet socket
+   * will use to dispatch handlers for any asynchronous operations performed on
+   * the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_seq_packet_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+        io_context, protocol, native_socket)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_seq_packet_socket from another.
+  /**
+   * This constructor moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+   */
+  basic_seq_packet_socket(basic_seq_packet_socket&& other)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_seq_packet_socket from another.
+  /**
+   * This assignment operator moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+   */
+  basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_seq_packet_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_seq_packet_socket(
+      basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_seq_packet_socket from a socket of another protocol
+  /// type.
+  /**
+   * This assignment operator moves a sequenced packet socket from one object to
+   * another.
+   *
+   * @param other The other basic_seq_packet_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_seq_packet_socket>::type& operator=(
+        basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the socket.
+  /**
+   * This function destroys the socket, cancelling any outstanding asynchronous
+   * operations associated with the socket as if by calling @c cancel.
+   */
+  ~basic_seq_packet_socket()
+  {
+  }
+
+  /// Send some data on the socket.
+  /**
+   * This function is used to send data on the sequenced packet socket. The
+   * function call will block until the data has been sent successfully, or an
+   * until error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.send(boost::asio::buffer(data, size), 0);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on the socket.
+  /**
+   * This function is used to send data on the sequenced packet socket. The
+   * function call will block the data has been sent successfully, or an until
+   * error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent. Returns 0 if an error occurred.
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref write function if you need to ensure that all data
+   * is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send data on the sequenced packet
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(boost::asio::buffer(data, size), 0, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive some data on the socket.
+  /**
+   * This function is used to receive data on the sequenced packet socket. The
+   * function call will block until data has been received successfully, or
+   * until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param out_flags After the receive call completes, contains flags
+   * associated with the received data. For example, if the
+   * socket_base::message_end_of_record bit is set then the received data marks
+   * the end of a record.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.receive(boost::asio::buffer(data, size), out_flags);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags& out_flags)
+  {
+    boost::system::error_code ec;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, 0, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    std::size_t s = this->get_service().receive_with_flags(
+        this->get_implementation(), buffers, 0, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on the socket.
+  /**
+   * This function is used to receive data on the sequenced packet socket. The
+   * function call will block until data has been received successfully, or
+   * until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param in_flags Flags specifying how the receive call is to be made.
+   *
+   * @param out_flags After the receive call completes, contains flags
+   * associated with the received data. For example, if the
+   * socket_base::message_end_of_record bit is set then the received data marks
+   * the end of a record.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that the
+   * requested amount of data is read before the blocking operation completes.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.receive(boost::asio::buffer(data, size), 0, out_flags);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags in_flags,
+      socket_base::message_flags& out_flags)
+  {
+    boost::system::error_code ec;
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, in_flags, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    std::size_t s = this->get_service().receive_with_flags(
+        this->get_implementation(), buffers, in_flags, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the sequenced packet socket. The
+   * function call will block until data has been received successfully, or
+   * until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param in_flags Flags specifying how the receive call is to be made.
+   *
+   * @param out_flags After the receive call completes, contains flags
+   * associated with the received data. For example, if the
+   * socket_base::message_end_of_record bit is set then the received data marks
+   * the end of a record.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received. Returns 0 if an error occurred.
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that the
+   * requested amount of data is read before the blocking operation completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags in_flags,
+      socket_base::message_flags& out_flags, boost::system::error_code& ec)
+  {
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().receive(this->get_implementation(),
+        buffers, in_flags, out_flags, ec);
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().receive_with_flags(this->get_implementation(),
+        buffers, in_flags, out_flags, ec);
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive data from the sequenced
+   * packet socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param out_flags Once the asynchronous operation completes, contains flags
+   * associated with the received data. For example, if the
+   * socket_base::message_end_of_record bit is set then the received data marks
+   * the end of a record. The caller must guarantee that the referenced
+   * variable remains valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags& out_flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(
+        this->get_implementation(), buffers, 0, out_flags,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_with_flags(
+        this->get_implementation(), buffers, 0, out_flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive data from the sequenced
+   * data socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param in_flags Flags specifying how the receive call is to be made.
+   *
+   * @param out_flags Once the asynchronous operation completes, contains flags
+   * associated with the received data. For example, if the
+   * socket_base::message_end_of_record bit is set then the received data marks
+   * the end of a record. The caller must guarantee that the referenced
+   * variable remains valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(
+   *     boost::asio::buffer(data, size),
+   *     0, out_flags, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags in_flags,
+      socket_base::message_flags& out_flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(
+        this->get_implementation(), buffers, in_flags, out_flags,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive_with_flags(
+        this->get_implementation(), buffers, in_flags, out_flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP

+ 690 - 0
cpir-read/boost/boost/asio/basic_serial_port.hpp

@@ -0,0 +1,690 @@
+//
+// basic_serial_port.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SERIAL_PORT_HPP
+#define BOOST_ASIO_BASIC_SERIAL_PORT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+  || defined(GENERATING_DOCUMENTATION)
+
+#include <string>
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/serial_port_base.hpp>
+#include <boost/asio/serial_port_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides serial port functionality.
+/**
+ * The basic_serial_port class template provides functionality that is common
+ * to all serial ports.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename SerialPortService = serial_port_service>
+class basic_serial_port
+  : public basic_io_object<SerialPortService>,
+    public serial_port_base
+{
+public:
+  /// The native representation of a serial port.
+  typedef typename SerialPortService::native_handle_type native_handle_type;
+
+  /// A basic_serial_port is always the lowest layer.
+  typedef basic_serial_port<SerialPortService> lowest_layer_type;
+
+  /// Construct a basic_serial_port without opening it.
+  /**
+   * This constructor creates a serial port without opening it.
+   *
+   * @param io_context The io_context object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   */
+  explicit basic_serial_port(boost::asio::io_context& io_context)
+    : basic_io_object<SerialPortService>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_serial_port.
+  /**
+   * This constructor creates and opens a serial port for the specified device
+   * name.
+   *
+   * @param io_context The io_context object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param device The platform-specific device name for this serial
+   * port.
+   */
+  explicit basic_serial_port(boost::asio::io_context& io_context,
+      const char* device)
+    : basic_io_object<SerialPortService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), device, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Construct and open a basic_serial_port.
+  /**
+   * This constructor creates and opens a serial port for the specified device
+   * name.
+   *
+   * @param io_context The io_context object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param device The platform-specific device name for this serial
+   * port.
+   */
+  explicit basic_serial_port(boost::asio::io_context& io_context,
+      const std::string& device)
+    : basic_io_object<SerialPortService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), device, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Construct a basic_serial_port on an existing native serial port.
+  /**
+   * This constructor creates a serial port object to hold an existing native
+   * serial port.
+   *
+   * @param io_context The io_context object that the serial port will use to
+   * dispatch handlers for any asynchronous operations performed on the port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_serial_port(boost::asio::io_context& io_context,
+      const native_handle_type& native_serial_port)
+    : basic_io_object<SerialPortService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        native_serial_port, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_serial_port from another.
+  /**
+   * This constructor moves a serial port from one object to another.
+   *
+   * @param other The other basic_serial_port object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_serial_port(io_context&) constructor.
+   */
+  basic_serial_port(basic_serial_port&& other)
+    : basic_io_object<SerialPortService>(
+        BOOST_ASIO_MOVE_CAST(basic_serial_port)(other))
+  {
+  }
+
+  /// Move-assign a basic_serial_port from another.
+  /**
+   * This assignment operator moves a serial port from one object to another.
+   *
+   * @param other The other basic_serial_port object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_serial_port(io_context&) constructor.
+   */
+  basic_serial_port& operator=(basic_serial_port&& other)
+  {
+    basic_io_object<SerialPortService>::operator=(
+        BOOST_ASIO_MOVE_CAST(basic_serial_port)(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Get a reference to the lowest layer.
+  /**
+   * This function returns a reference to the lowest layer in a stack of
+   * layers. Since a basic_serial_port cannot contain any further layers, it
+   * simply returns a reference to itself.
+   *
+   * @return A reference to the lowest layer in the stack of layers. Ownership
+   * is not transferred to the caller.
+   */
+  lowest_layer_type& lowest_layer()
+  {
+    return *this;
+  }
+
+  /// Get a const reference to the lowest layer.
+  /**
+   * This function returns a const reference to the lowest layer in a stack of
+   * layers. Since a basic_serial_port cannot contain any further layers, it
+   * simply returns a reference to itself.
+   *
+   * @return A const reference to the lowest layer in the stack of layers.
+   * Ownership is not transferred to the caller.
+   */
+  const lowest_layer_type& lowest_layer() const
+  {
+    return *this;
+  }
+
+  /// Open the serial port using the specified device name.
+  /**
+   * This function opens the serial port for the specified device name.
+   *
+   * @param device The platform-specific device name.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void open(const std::string& device)
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), device, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Open the serial port using the specified device name.
+  /**
+   * This function opens the serial port using the given platform-specific
+   * device name.
+   *
+   * @param device The platform-specific device name.
+   *
+   * @param ec Set the indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
+      boost::system::error_code& ec)
+  {
+    this->get_service().open(this->get_implementation(), device, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Assign an existing native serial port to the serial port.
+  /*
+   * This function opens the serial port to hold an existing native serial port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void assign(const native_handle_type& native_serial_port)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        native_serial_port, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+  /// Assign an existing native serial port to the serial port.
+  /*
+   * This function opens the serial port to hold an existing native serial port.
+   *
+   * @param native_serial_port A native serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
+      boost::system::error_code& ec)
+  {
+    this->get_service().assign(this->get_implementation(),
+        native_serial_port, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the serial port is open.
+  bool is_open() const
+  {
+    return this->get_service().is_open(this->get_implementation());
+  }
+
+  /// Close the serial port.
+  /**
+   * This function is used to close the serial port. Any asynchronous read or
+   * write operations will be cancelled immediately, and will complete with the
+   * boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void close()
+  {
+    boost::system::error_code ec;
+    this->get_service().close(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "close");
+  }
+
+  /// Close the serial port.
+  /**
+   * This function is used to close the serial port. Any asynchronous read or
+   * write operations will be cancelled immediately, and will complete with the
+   * boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    this->get_service().close(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get the native serial port representation.
+  /**
+   * This function may be used to obtain the underlying representation of the
+   * serial port. This is intended to allow access to native serial port
+   * functionality that is not otherwise provided.
+   */
+  native_handle_type native_handle()
+  {
+    return this->get_service().native_handle(this->get_implementation());
+  }
+
+  /// Cancel all asynchronous operations associated with the serial port.
+  /**
+   * This function causes all outstanding asynchronous read or write operations
+   * to finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void cancel()
+  {
+    boost::system::error_code ec;
+    this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+  }
+
+  /// Cancel all asynchronous operations associated with the serial port.
+  /**
+   * This function causes all outstanding asynchronous read or write operations
+   * to finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+  {
+    this->get_service().cancel(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Send a break sequence to the serial port.
+  /**
+   * This function causes a break sequence of platform-specific duration to be
+   * sent out the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void send_break()
+  {
+    boost::system::error_code ec;
+    this->get_service().send_break(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "send_break");
+  }
+
+  /// Send a break sequence to the serial port.
+  /**
+   * This function causes a break sequence of platform-specific duration to be
+   * sent out the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
+  {
+    this->get_service().send_break(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Set an option on the serial port.
+  /**
+   * This function is used to set an option on the serial port.
+   *
+   * @param option The option value to be set on the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa SettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename SettableSerialPortOption>
+  void set_option(const SettableSerialPortOption& option)
+  {
+    boost::system::error_code ec;
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "set_option");
+  }
+
+  /// Set an option on the serial port.
+  /**
+   * This function is used to set an option on the serial port.
+   *
+   * @param option The option value to be set on the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa SettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename SettableSerialPortOption>
+  BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
+      boost::system::error_code& ec)
+  {
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get an option from the serial port.
+  /**
+   * This function is used to get the current value of an option on the serial
+   * port.
+   *
+   * @param option The option value to be obtained from the serial port.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa GettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename GettableSerialPortOption>
+  void get_option(GettableSerialPortOption& option)
+  {
+    boost::system::error_code ec;
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "get_option");
+  }
+
+  /// Get an option from the serial port.
+  /**
+   * This function is used to get the current value of an option on the serial
+   * port.
+   *
+   * @param option The option value to be obtained from the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa GettableSerialPortOption @n
+   * boost::asio::serial_port_base::baud_rate @n
+   * boost::asio::serial_port_base::flow_control @n
+   * boost::asio::serial_port_base::parity @n
+   * boost::asio::serial_port_base::stop_bits @n
+   * boost::asio::serial_port_base::character_size
+   */
+  template <typename GettableSerialPortOption>
+  BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
+      boost::system::error_code& ec)
+  {
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Write some data to the serial port.
+  /**
+   * This function is used to write data to the serial port. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   *
+   * @returns The number of bytes written.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.write_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().write_some(
+        this->get_implementation(), buffers, ec);
+    boost::asio::detail::throw_error(ec, "write_some");
+    return s;
+  }
+
+  /// Write some data to the serial port.
+  /**
+   * This function is used to write data to the serial port. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes written. Returns 0 if an error occurred.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().write_some(
+        this->get_implementation(), buffers, ec);
+  }
+
+  /// Start an asynchronous write.
+  /**
+   * This function is used to asynchronously write data to the serial port.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be written to the serial port.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the write operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes written.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The write operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write function if you need to ensure that all
+   * data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.async_write_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_write_some(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+    return this->get_service().async_write_some(this->get_implementation(),
+        buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+  }
+
+  /// Read some data from the serial port.
+  /**
+   * This function is used to read data from the serial port. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @returns The number of bytes read.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.read_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().read_some(
+        this->get_implementation(), buffers, ec);
+    boost::asio::detail::throw_error(ec, "read_some");
+    return s;
+  }
+
+  /// Read some data from the serial port.
+  /**
+   * This function is used to read data from the serial port. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes read. Returns 0 if an error occurred.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().read_some(
+        this->get_implementation(), buffers, ec);
+  }
+
+  /// Start an asynchronous read.
+  /**
+   * This function is used to asynchronously read data from the serial port.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the read operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes read.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The read operation may not read all of the requested number of bytes.
+   * Consider using the @ref async_read function if you need to ensure that the
+   * requested amount of data is read before the asynchronous operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * serial_port.async_read_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_read_some(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+    return this->get_service().async_read_some(this->get_implementation(),
+        buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+       //   || defined(GENERATING_DOCUMENTATION)
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP

+ 393 - 0
cpir-read/boost/boost/asio/basic_signal_set.hpp

@@ -0,0 +1,393 @@
+//
+// basic_signal_set.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SIGNAL_SET_HPP
+#define BOOST_ASIO_BASIC_SIGNAL_SET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/signal_set_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides signal functionality.
+/**
+ * The basic_signal_set class template provides the ability to perform an
+ * asynchronous wait for one or more signals to occur.
+ *
+ * Most applications will use the boost::asio::signal_set typedef.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Example
+ * Performing an asynchronous wait:
+ * @code
+ * void handler(
+ *     const boost::system::error_code& error,
+ *     int signal_number)
+ * {
+ *   if (!error)
+ *   {
+ *     // A signal occurred.
+ *   }
+ * }
+ *
+ * ...
+ *
+ * // Construct a signal set registered for process termination.
+ * boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
+ *
+ * // Start an asynchronous wait for one of the signals to occur.
+ * signals.async_wait(handler);
+ * @endcode
+ *
+ * @par Queueing of signal notifications
+ *
+ * If a signal is registered with a signal_set, and the signal occurs when
+ * there are no waiting handlers, then the signal notification is queued. The
+ * next async_wait operation on that signal_set will dequeue the notification.
+ * If multiple notifications are queued, subsequent async_wait operations
+ * dequeue them one at a time. Signal notifications are dequeued in order of
+ * ascending signal number.
+ *
+ * If a signal number is removed from a signal_set (using the @c remove or @c
+ * erase member functions) then any queued notifications for that signal are
+ * discarded.
+ *
+ * @par Multiple registration of signals
+ *
+ * The same signal number may be registered with different signal_set objects.
+ * When the signal occurs, one handler is called for each signal_set object.
+ *
+ * Note that multiple registration only works for signals that are registered
+ * using Asio. The application must not also register a signal handler using
+ * functions such as @c signal() or @c sigaction().
+ *
+ * @par Signal masking on POSIX platforms
+ *
+ * POSIX allows signals to be blocked using functions such as @c sigprocmask()
+ * and @c pthread_sigmask(). For signals to be delivered, programs must ensure
+ * that any signals registered using signal_set objects are unblocked in at
+ * least one thread.
+ */
+template <typename SignalSetService = signal_set_service>
+class basic_signal_set
+  : public basic_io_object<SignalSetService>
+{
+public:
+  /// Construct a signal set without adding any signals.
+  /**
+   * This constructor creates a signal set without registering for any signals.
+   *
+   * @param io_context The io_context object that the signal set will use to
+   * dispatch handlers for any asynchronous operations performed on the set.
+   */
+  explicit basic_signal_set(boost::asio::io_context& io_context)
+    : basic_io_object<SignalSetService>(io_context)
+  {
+  }
+
+  /// Construct a signal set and add one signal.
+  /**
+   * This constructor creates a signal set and registers for one signal.
+   *
+   * @param io_context The io_context object that the signal set will use to
+   * dispatch handlers for any asynchronous operations performed on the set.
+   *
+   * @param signal_number_1 The signal number to be added.
+   *
+   * @note This constructor is equivalent to performing:
+   * @code boost::asio::signal_set signals(io_context);
+   * signals.add(signal_number_1); @endcode
+   */
+  basic_signal_set(boost::asio::io_context& io_context, int signal_number_1)
+    : basic_io_object<SignalSetService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().add(this->get_implementation(), signal_number_1, ec);
+    boost::asio::detail::throw_error(ec, "add");
+  }
+
+  /// Construct a signal set and add two signals.
+  /**
+   * This constructor creates a signal set and registers for two signals.
+   *
+   * @param io_context The io_context object that the signal set will use to
+   * dispatch handlers for any asynchronous operations performed on the set.
+   *
+   * @param signal_number_1 The first signal number to be added.
+   *
+   * @param signal_number_2 The second signal number to be added.
+   *
+   * @note This constructor is equivalent to performing:
+   * @code boost::asio::signal_set signals(io_context);
+   * signals.add(signal_number_1);
+   * signals.add(signal_number_2); @endcode
+   */
+  basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
+      int signal_number_2)
+    : basic_io_object<SignalSetService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().add(this->get_implementation(), signal_number_1, ec);
+    boost::asio::detail::throw_error(ec, "add");
+    this->get_service().add(this->get_implementation(), signal_number_2, ec);
+    boost::asio::detail::throw_error(ec, "add");
+  }
+
+  /// Construct a signal set and add three signals.
+  /**
+   * This constructor creates a signal set and registers for three signals.
+   *
+   * @param io_context The io_context object that the signal set will use to
+   * dispatch handlers for any asynchronous operations performed on the set.
+   *
+   * @param signal_number_1 The first signal number to be added.
+   *
+   * @param signal_number_2 The second signal number to be added.
+   *
+   * @param signal_number_3 The third signal number to be added.
+   *
+   * @note This constructor is equivalent to performing:
+   * @code boost::asio::signal_set signals(io_context);
+   * signals.add(signal_number_1);
+   * signals.add(signal_number_2);
+   * signals.add(signal_number_3); @endcode
+   */
+  basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
+      int signal_number_2, int signal_number_3)
+    : basic_io_object<SignalSetService>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().add(this->get_implementation(), signal_number_1, ec);
+    boost::asio::detail::throw_error(ec, "add");
+    this->get_service().add(this->get_implementation(), signal_number_2, ec);
+    boost::asio::detail::throw_error(ec, "add");
+    this->get_service().add(this->get_implementation(), signal_number_3, ec);
+    boost::asio::detail::throw_error(ec, "add");
+  }
+
+  /// Add a signal to a signal_set.
+  /**
+   * This function adds the specified signal to the set. It has no effect if the
+   * signal is already in the set.
+   *
+   * @param signal_number The signal to be added to the set.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void add(int signal_number)
+  {
+    boost::system::error_code ec;
+    this->get_service().add(this->get_implementation(), signal_number, ec);
+    boost::asio::detail::throw_error(ec, "add");
+  }
+
+  /// Add a signal to a signal_set.
+  /**
+   * This function adds the specified signal to the set. It has no effect if the
+   * signal is already in the set.
+   *
+   * @param signal_number The signal to be added to the set.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID add(int signal_number, boost::system::error_code& ec)
+  {
+    this->get_service().add(this->get_implementation(), signal_number, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Remove a signal from a signal_set.
+  /**
+   * This function removes the specified signal from the set. It has no effect
+   * if the signal is not in the set.
+   *
+   * @param signal_number The signal to be removed from the set.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note Removes any notifications that have been queued for the specified
+   * signal number.
+   */
+  void remove(int signal_number)
+  {
+    boost::system::error_code ec;
+    this->get_service().remove(this->get_implementation(), signal_number, ec);
+    boost::asio::detail::throw_error(ec, "remove");
+  }
+
+  /// Remove a signal from a signal_set.
+  /**
+   * This function removes the specified signal from the set. It has no effect
+   * if the signal is not in the set.
+   *
+   * @param signal_number The signal to be removed from the set.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note Removes any notifications that have been queued for the specified
+   * signal number.
+   */
+  BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
+      boost::system::error_code& ec)
+  {
+    this->get_service().remove(this->get_implementation(), signal_number, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Remove all signals from a signal_set.
+  /**
+   * This function removes all signals from the set. It has no effect if the set
+   * is already empty.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note Removes all queued notifications.
+   */
+  void clear()
+  {
+    boost::system::error_code ec;
+    this->get_service().clear(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "clear");
+  }
+
+  /// Remove all signals from a signal_set.
+  /**
+   * This function removes all signals from the set. It has no effect if the set
+   * is already empty.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note Removes all queued notifications.
+   */
+  BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
+  {
+    this->get_service().clear(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Cancel all operations associated with the signal set.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the signal set. The handler for each cancelled
+   * operation will be invoked with the boost::asio::error::operation_aborted
+   * error code.
+   *
+   * Cancellation does not alter the set of registered signals.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If a registered signal occurred before cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  void cancel()
+  {
+    boost::system::error_code ec;
+    this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+  }
+
+  /// Cancel all operations associated with the signal set.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the signal set. The handler for each cancelled
+   * operation will be invoked with the boost::asio::error::operation_aborted
+   * error code.
+   *
+   * Cancellation does not alter the set of registered signals.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note If a registered signal occurred before cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+  {
+    this->get_service().cancel(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Start an asynchronous operation to wait for a signal to be delivered.
+  /**
+   * This function may be used to initiate an asynchronous wait against the
+   * signal set. It always returns immediately.
+   *
+   * For each call to async_wait(), the supplied handler will be called exactly
+   * once. The handler will be called when:
+   *
+   * @li One of the registered signals in the signal set occurs; or
+   *
+   * @li The signal set was cancelled, in which case the handler is passed the
+   * error code boost::asio::error::operation_aborted.
+   *
+   * @param handler The handler to be called when the signal occurs. Copies
+   * will be made of the handler as required. The function signature of the
+   * handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   int signal_number // Indicates which signal occurred.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename SignalHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
+      void (boost::system::error_code, int))
+  async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a SignalHandler.
+    BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
+
+    return this->get_service().async_wait(this->get_implementation(),
+        BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP

+ 1759 - 0
cpir-read/boost/boost/asio/basic_socket.hpp

@@ -0,0 +1,1759 @@
+//
+// basic_socket.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_HPP
+#define BOOST_ASIO_BASIC_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#  include <boost/asio/detail/winrt_ssocket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
+# elif defined(BOOST_ASIO_HAS_IOCP)
+#  include <boost/asio/detail/win_iocp_socket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
+# else
+#  include <boost/asio/detail/reactive_socket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
+# endif
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides socket functionality.
+/**
+ * The basic_socket class template provides functionality that is common to both
+ * stream-oriented and datagram-oriented sockets.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM>
+class basic_socket
+  : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
+    public socket_base
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef io_context::executor_type executor_type;
+
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+  /// A basic_socket is always the lowest layer.
+  typedef basic_socket<Protocol BOOST_ASIO_SVC_TARG> lowest_layer_type;
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+  /// Construct a basic_socket without opening it.
+  /**
+   * This constructor creates a socket without opening it.
+   *
+   * @param io_context The io_context object that the socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   */
+  explicit basic_socket(boost::asio::io_context& io_context)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_socket.
+  /**
+   * This constructor creates and opens a socket.
+   *
+   * @param io_context The io_context object that the socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Construct a basic_socket, opening it and binding it to the given local
+  /// endpoint.
+  /**
+   * This constructor creates a socket and automatically opens it bound to the
+   * specified endpoint on the local machine. The protocol used is the protocol
+   * associated with the given endpoint.
+   *
+   * @param io_context The io_context object that the socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the socket will
+   * be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_socket(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    const protocol_type protocol = endpoint.protocol();
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    boost::asio::detail::throw_error(ec, "bind");
+  }
+
+  /// Construct a basic_socket on an existing native socket.
+  /**
+   * This constructor creates a socket object to hold an existing native socket.
+   *
+   * @param io_context The io_context object that the socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket A native socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_socket, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_socket from another.
+  /**
+   * This constructor moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  basic_socket(basic_socket&& other)
+    : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_socket from another.
+  /**
+   * This assignment operator moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  basic_socket& operator=(basic_socket&& other)
+  {
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+    return *this;
+  }
+
+  // All sockets have access to each other's implementations.
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  friend class basic_socket;
+
+  /// Move-construct a basic_socket from a socket of another protocol type.
+  /**
+   * This constructor moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_socket(basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_io_object<BOOST_ASIO_SVC_T>(
+        other.get_service(), other.get_implementation())
+  {
+  }
+
+  /// Move-assign a basic_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a socket from one object to another.
+   *
+   * @param other The other basic_socket object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_socket>::type& operator=(
+        basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket tmp(std::move(other));
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_context()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_service()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+  }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+  /// Get a reference to the lowest layer.
+  /**
+   * This function returns a reference to the lowest layer in a stack of
+   * layers. Since a basic_socket cannot contain any further layers, it simply
+   * returns a reference to itself.
+   *
+   * @return A reference to the lowest layer in the stack of layers. Ownership
+   * is not transferred to the caller.
+   */
+  lowest_layer_type& lowest_layer()
+  {
+    return *this;
+  }
+
+  /// Get a const reference to the lowest layer.
+  /**
+   * This function returns a const reference to the lowest layer in a stack of
+   * layers. Since a basic_socket cannot contain any further layers, it simply
+   * returns a reference to itself.
+   *
+   * @return A const reference to the lowest layer in the stack of layers.
+   * Ownership is not transferred to the caller.
+   */
+  const lowest_layer_type& lowest_layer() const
+  {
+    return *this;
+  }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+  /// Open the socket using the specified protocol.
+  /**
+   * This function opens the socket so that it will use the specified protocol.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * socket.open(boost::asio::ip::tcp::v4());
+   * @endcode
+   */
+  void open(const protocol_type& protocol = protocol_type())
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Open the socket using the specified protocol.
+  /**
+   * This function opens the socket so that it will use the specified protocol.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::system::error_code ec;
+   * socket.open(boost::asio::ip::tcp::v4(), ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
+      boost::system::error_code& ec)
+  {
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Assign an existing native socket to the socket.
+  /*
+   * This function opens the socket to hold an existing native socket.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param native_socket A native socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void assign(const protocol_type& protocol,
+      const native_handle_type& native_socket)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_socket, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+  /// Assign an existing native socket to the socket.
+  /*
+   * This function opens the socket to hold an existing native socket.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param native_socket A native socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
+      const native_handle_type& native_socket, boost::system::error_code& ec)
+  {
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_socket, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the socket is open.
+  bool is_open() const
+  {
+    return this->get_service().is_open(this->get_implementation());
+  }
+
+  /// Close the socket.
+  /**
+   * This function is used to close the socket. Any asynchronous send, receive
+   * or connect operations will be cancelled immediately, and will complete
+   * with the boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure. Note that, even if
+   * the function indicates an error, the underlying descriptor is closed.
+   *
+   * @note For portable behaviour with respect to graceful closure of a
+   * connected socket, call shutdown() before closing the socket.
+   */
+  void close()
+  {
+    boost::system::error_code ec;
+    this->get_service().close(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "close");
+  }
+
+  /// Close the socket.
+  /**
+   * This function is used to close the socket. Any asynchronous send, receive
+   * or connect operations will be cancelled immediately, and will complete
+   * with the boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any. Note that, even if
+   * the function indicates an error, the underlying descriptor is closed.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * socket.close(ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   *
+   * @note For portable behaviour with respect to graceful closure of a
+   * connected socket, call shutdown() before closing the socket.
+   */
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    this->get_service().close(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Release ownership of the underlying native socket.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error. Ownership
+   * of the native socket is then transferred to the caller.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note This function is unsupported on Windows versions prior to Windows
+   * 8.1, and will fail with boost::asio::error::operation_not_supported on
+   * these platforms.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+  __declspec(deprecated("This function always fails with "
+        "operation_not_supported when used on Windows versions "
+        "prior to Windows 8.1."))
+#endif
+  native_handle_type release()
+  {
+    boost::system::error_code ec;
+    native_handle_type s = this->get_service().release(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "release");
+    return s;
+  }
+
+  /// Release ownership of the underlying native socket.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error. Ownership
+   * of the native socket is then transferred to the caller.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note This function is unsupported on Windows versions prior to Windows
+   * 8.1, and will fail with boost::asio::error::operation_not_supported on
+   * these platforms.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+  __declspec(deprecated("This function always fails with "
+        "operation_not_supported when used on Windows versions "
+        "prior to Windows 8.1."))
+#endif
+  native_handle_type release(boost::system::error_code& ec)
+  {
+    return this->get_service().release(this->get_implementation(), ec);
+  }
+
+  /// Get the native socket representation.
+  /**
+   * This function may be used to obtain the underlying representation of the
+   * socket. This is intended to allow access to native socket functionality
+   * that is not otherwise provided.
+   */
+  native_handle_type native_handle()
+  {
+    return this->get_service().native_handle(this->get_implementation());
+  }
+
+  /// Cancel all asynchronous operations associated with the socket.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note Calls to cancel() will always fail with
+   * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+   * Server 2003, and earlier versions of Windows, unless
+   * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+   * two issues that should be considered before enabling its use:
+   *
+   * @li It will only cancel asynchronous operations that were initiated in the
+   * current thread.
+   *
+   * @li It can appear to complete without error, but the request to cancel the
+   * unfinished operations may be silently ignored by the operating system.
+   * Whether it works or not seems to depend on the drivers that are installed.
+   *
+   * For portable cancellation, consider using one of the following
+   * alternatives:
+   *
+   * @li Disable asio's I/O completion port backend by defining
+   * BOOST_ASIO_DISABLE_IOCP.
+   *
+   * @li Use the close() function to simultaneously cancel the outstanding
+   * operations and close the socket.
+   *
+   * When running on Windows Vista, Windows Server 2008, and later, the
+   * CancelIoEx function is always used. This function does not have the
+   * problems described above.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+  && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+  __declspec(deprecated("By default, this function always fails with "
+        "operation_not_supported when used on Windows XP, Windows Server 2003, "
+        "or earlier. Consult documentation for details."))
+#endif
+  void cancel()
+  {
+    boost::system::error_code ec;
+    this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+  }
+
+  /// Cancel all asynchronous operations associated with the socket.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note Calls to cancel() will always fail with
+   * boost::asio::error::operation_not_supported when run on Windows XP, Windows
+   * Server 2003, and earlier versions of Windows, unless
+   * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
+   * two issues that should be considered before enabling its use:
+   *
+   * @li It will only cancel asynchronous operations that were initiated in the
+   * current thread.
+   *
+   * @li It can appear to complete without error, but the request to cancel the
+   * unfinished operations may be silently ignored by the operating system.
+   * Whether it works or not seems to depend on the drivers that are installed.
+   *
+   * For portable cancellation, consider using one of the following
+   * alternatives:
+   *
+   * @li Disable asio's I/O completion port backend by defining
+   * BOOST_ASIO_DISABLE_IOCP.
+   *
+   * @li Use the close() function to simultaneously cancel the outstanding
+   * operations and close the socket.
+   *
+   * When running on Windows Vista, Windows Server 2008, and later, the
+   * CancelIoEx function is always used. This function does not have the
+   * problems described above.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
+  && !defined(BOOST_ASIO_ENABLE_CANCELIO)
+  __declspec(deprecated("By default, this function always fails with "
+        "operation_not_supported when used on Windows XP, Windows Server 2003, "
+        "or earlier. Consult documentation for details."))
+#endif
+  BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+  {
+    this->get_service().cancel(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the socket is at the out-of-band data mark.
+  /**
+   * This function is used to check whether the socket input is currently
+   * positioned at the out-of-band data mark.
+   *
+   * @return A bool indicating whether the socket is at the out-of-band data
+   * mark.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  bool at_mark() const
+  {
+    boost::system::error_code ec;
+    bool b = this->get_service().at_mark(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "at_mark");
+    return b;
+  }
+
+  /// Determine whether the socket is at the out-of-band data mark.
+  /**
+   * This function is used to check whether the socket input is currently
+   * positioned at the out-of-band data mark.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return A bool indicating whether the socket is at the out-of-band data
+   * mark.
+   */
+  bool at_mark(boost::system::error_code& ec) const
+  {
+    return this->get_service().at_mark(this->get_implementation(), ec);
+  }
+
+  /// Determine the number of bytes available for reading.
+  /**
+   * This function is used to determine the number of bytes that may be read
+   * without blocking.
+   *
+   * @return The number of bytes that may be read without blocking, or 0 if an
+   * error occurs.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  std::size_t available() const
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().available(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "available");
+    return s;
+  }
+
+  /// Determine the number of bytes available for reading.
+  /**
+   * This function is used to determine the number of bytes that may be read
+   * without blocking.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of bytes that may be read without blocking, or 0 if an
+   * error occurs.
+   */
+  std::size_t available(boost::system::error_code& ec) const
+  {
+    return this->get_service().available(this->get_implementation(), ec);
+  }
+
+  /// Bind the socket to the given local endpoint.
+  /**
+   * This function binds the socket to the specified endpoint on the local
+   * machine.
+   *
+   * @param endpoint An endpoint on the local machine to which the socket will
+   * be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * socket.open(boost::asio::ip::tcp::v4());
+   * socket.bind(boost::asio::ip::tcp::endpoint(
+   *       boost::asio::ip::tcp::v4(), 12345));
+   * @endcode
+   */
+  void bind(const endpoint_type& endpoint)
+  {
+    boost::system::error_code ec;
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    boost::asio::detail::throw_error(ec, "bind");
+  }
+
+  /// Bind the socket to the given local endpoint.
+  /**
+   * This function binds the socket to the specified endpoint on the local
+   * machine.
+   *
+   * @param endpoint An endpoint on the local machine to which the socket will
+   * be bound.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * socket.open(boost::asio::ip::tcp::v4());
+   * boost::system::error_code ec;
+   * socket.bind(boost::asio::ip::tcp::endpoint(
+   *       boost::asio::ip::tcp::v4(), 12345), ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
+      boost::system::error_code& ec)
+  {
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Connect the socket to the specified endpoint.
+  /**
+   * This function is used to connect a socket to the specified remote endpoint.
+   * The function call will block until the connection is successfully made or
+   * an error occurs.
+   *
+   * The socket is automatically opened if it is not already open. If the
+   * connect fails, and the socket was automatically opened, the socket is
+   * not returned to the closed state.
+   *
+   * @param peer_endpoint The remote endpoint to which the socket will be
+   * connected.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.connect(endpoint);
+   * @endcode
+   */
+  void connect(const endpoint_type& peer_endpoint)
+  {
+    boost::system::error_code ec;
+    if (!is_open())
+    {
+      this->get_service().open(this->get_implementation(),
+          peer_endpoint.protocol(), ec);
+      boost::asio::detail::throw_error(ec, "connect");
+    }
+    this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
+    boost::asio::detail::throw_error(ec, "connect");
+  }
+
+  /// Connect the socket to the specified endpoint.
+  /**
+   * This function is used to connect a socket to the specified remote endpoint.
+   * The function call will block until the connection is successfully made or
+   * an error occurs.
+   *
+   * The socket is automatically opened if it is not already open. If the
+   * connect fails, and the socket was automatically opened, the socket is
+   * not returned to the closed state.
+   *
+   * @param peer_endpoint The remote endpoint to which the socket will be
+   * connected.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * boost::system::error_code ec;
+   * socket.connect(endpoint, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
+      boost::system::error_code& ec)
+  {
+    if (!is_open())
+    {
+      this->get_service().open(this->get_implementation(),
+            peer_endpoint.protocol(), ec);
+      if (ec)
+      {
+        BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+      }
+    }
+
+    this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Start an asynchronous connect.
+  /**
+   * This function is used to asynchronously connect a socket to the specified
+   * remote endpoint. The function call always returns immediately.
+   *
+   * The socket is automatically opened if it is not already open. If the
+   * connect fails, and the socket was automatically opened, the socket is
+   * not returned to the closed state.
+   *
+   * @param peer_endpoint The remote endpoint to which the socket will be
+   * connected. Copies will be made of the endpoint object as required.
+   *
+   * @param handler The handler to be called when the connection operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void connect_handler(const boost::system::error_code& error)
+   * {
+   *   if (!error)
+   *   {
+   *     // Connect succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint(
+   *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
+   * socket.async_connect(endpoint, connect_handler);
+   * @endcode
+   */
+  template <typename ConnectHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
+      void (boost::system::error_code))
+  async_connect(const endpoint_type& peer_endpoint,
+      BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ConnectHandler.
+    BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
+
+    if (!is_open())
+    {
+      boost::system::error_code ec;
+      const protocol_type protocol = peer_endpoint.protocol();
+      this->get_service().open(this->get_implementation(), protocol, ec);
+      if (ec)
+      {
+        async_completion<ConnectHandler,
+          void (boost::system::error_code)> init(handler);
+
+        boost::asio::post(this->get_executor(),
+            boost::asio::detail::bind_handler(
+              BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(
+                ConnectHandler, void (boost::system::error_code)))(
+                  init.completion_handler), ec));
+
+        return init.result.get();
+      }
+    }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_connect(this->get_implementation(),
+        peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ConnectHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_connect(
+        this->get_implementation(), peer_endpoint, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Set an option on the socket.
+  /**
+   * This function is used to set an option on the socket.
+   *
+   * @param option The new option value to be set on the socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa SettableSocketOption @n
+   * boost::asio::socket_base::broadcast @n
+   * boost::asio::socket_base::do_not_route @n
+   * boost::asio::socket_base::keep_alive @n
+   * boost::asio::socket_base::linger @n
+   * boost::asio::socket_base::receive_buffer_size @n
+   * boost::asio::socket_base::receive_low_watermark @n
+   * boost::asio::socket_base::reuse_address @n
+   * boost::asio::socket_base::send_buffer_size @n
+   * boost::asio::socket_base::send_low_watermark @n
+   * boost::asio::ip::multicast::join_group @n
+   * boost::asio::ip::multicast::leave_group @n
+   * boost::asio::ip::multicast::enable_loopback @n
+   * boost::asio::ip::multicast::outbound_interface @n
+   * boost::asio::ip::multicast::hops @n
+   * boost::asio::ip::tcp::no_delay
+   *
+   * @par Example
+   * Setting the IPPROTO_TCP/TCP_NODELAY option:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::no_delay option(true);
+   * socket.set_option(option);
+   * @endcode
+   */
+  template <typename SettableSocketOption>
+  void set_option(const SettableSocketOption& option)
+  {
+    boost::system::error_code ec;
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "set_option");
+  }
+
+  /// Set an option on the socket.
+  /**
+   * This function is used to set an option on the socket.
+   *
+   * @param option The new option value to be set on the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa SettableSocketOption @n
+   * boost::asio::socket_base::broadcast @n
+   * boost::asio::socket_base::do_not_route @n
+   * boost::asio::socket_base::keep_alive @n
+   * boost::asio::socket_base::linger @n
+   * boost::asio::socket_base::receive_buffer_size @n
+   * boost::asio::socket_base::receive_low_watermark @n
+   * boost::asio::socket_base::reuse_address @n
+   * boost::asio::socket_base::send_buffer_size @n
+   * boost::asio::socket_base::send_low_watermark @n
+   * boost::asio::ip::multicast::join_group @n
+   * boost::asio::ip::multicast::leave_group @n
+   * boost::asio::ip::multicast::enable_loopback @n
+   * boost::asio::ip::multicast::outbound_interface @n
+   * boost::asio::ip::multicast::hops @n
+   * boost::asio::ip::tcp::no_delay
+   *
+   * @par Example
+   * Setting the IPPROTO_TCP/TCP_NODELAY option:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::no_delay option(true);
+   * boost::system::error_code ec;
+   * socket.set_option(option, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  template <typename SettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
+      boost::system::error_code& ec)
+  {
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get an option from the socket.
+  /**
+   * This function is used to get the current value of an option on the socket.
+   *
+   * @param option The option value to be obtained from the socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa GettableSocketOption @n
+   * boost::asio::socket_base::broadcast @n
+   * boost::asio::socket_base::do_not_route @n
+   * boost::asio::socket_base::keep_alive @n
+   * boost::asio::socket_base::linger @n
+   * boost::asio::socket_base::receive_buffer_size @n
+   * boost::asio::socket_base::receive_low_watermark @n
+   * boost::asio::socket_base::reuse_address @n
+   * boost::asio::socket_base::send_buffer_size @n
+   * boost::asio::socket_base::send_low_watermark @n
+   * boost::asio::ip::multicast::join_group @n
+   * boost::asio::ip::multicast::leave_group @n
+   * boost::asio::ip::multicast::enable_loopback @n
+   * boost::asio::ip::multicast::outbound_interface @n
+   * boost::asio::ip::multicast::hops @n
+   * boost::asio::ip::tcp::no_delay
+   *
+   * @par Example
+   * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket::keep_alive option;
+   * socket.get_option(option);
+   * bool is_set = option.value();
+   * @endcode
+   */
+  template <typename GettableSocketOption>
+  void get_option(GettableSocketOption& option) const
+  {
+    boost::system::error_code ec;
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "get_option");
+  }
+
+  /// Get an option from the socket.
+  /**
+   * This function is used to get the current value of an option on the socket.
+   *
+   * @param option The option value to be obtained from the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa GettableSocketOption @n
+   * boost::asio::socket_base::broadcast @n
+   * boost::asio::socket_base::do_not_route @n
+   * boost::asio::socket_base::keep_alive @n
+   * boost::asio::socket_base::linger @n
+   * boost::asio::socket_base::receive_buffer_size @n
+   * boost::asio::socket_base::receive_low_watermark @n
+   * boost::asio::socket_base::reuse_address @n
+   * boost::asio::socket_base::send_buffer_size @n
+   * boost::asio::socket_base::send_low_watermark @n
+   * boost::asio::ip::multicast::join_group @n
+   * boost::asio::ip::multicast::leave_group @n
+   * boost::asio::ip::multicast::enable_loopback @n
+   * boost::asio::ip::multicast::outbound_interface @n
+   * boost::asio::ip::multicast::hops @n
+   * boost::asio::ip::tcp::no_delay
+   *
+   * @par Example
+   * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket::keep_alive option;
+   * boost::system::error_code ec;
+   * socket.get_option(option, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * bool is_set = option.value();
+   * @endcode
+   */
+  template <typename GettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
+      boost::system::error_code& ec) const
+  {
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Perform an IO control command on the socket.
+  /**
+   * This function is used to execute an IO control command on the socket.
+   *
+   * @param command The IO control command to be performed on the socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa IoControlCommand @n
+   * boost::asio::socket_base::bytes_readable @n
+   * boost::asio::socket_base::non_blocking_io
+   *
+   * @par Example
+   * Getting the number of bytes ready to read:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket::bytes_readable command;
+   * socket.io_control(command);
+   * std::size_t bytes_readable = command.get();
+   * @endcode
+   */
+  template <typename IoControlCommand>
+  void io_control(IoControlCommand& command)
+  {
+    boost::system::error_code ec;
+    this->get_service().io_control(this->get_implementation(), command, ec);
+    boost::asio::detail::throw_error(ec, "io_control");
+  }
+
+  /// Perform an IO control command on the socket.
+  /**
+   * This function is used to execute an IO control command on the socket.
+   *
+   * @param command The IO control command to be performed on the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa IoControlCommand @n
+   * boost::asio::socket_base::bytes_readable @n
+   * boost::asio::socket_base::non_blocking_io
+   *
+   * @par Example
+   * Getting the number of bytes ready to read:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket::bytes_readable command;
+   * boost::system::error_code ec;
+   * socket.io_control(command, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * std::size_t bytes_readable = command.get();
+   * @endcode
+   */
+  template <typename IoControlCommand>
+  BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
+      boost::system::error_code& ec)
+  {
+    this->get_service().io_control(this->get_implementation(), command, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the socket.
+  /**
+   * @returns @c true if the socket's synchronous operations will fail with
+   * boost::asio::error::would_block if they are unable to perform the requested
+   * operation immediately. If @c false, synchronous operations will block
+   * until complete.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  bool non_blocking() const
+  {
+    return this->get_service().non_blocking(this->get_implementation());
+  }
+
+  /// Sets the non-blocking mode of the socket.
+  /**
+   * @param mode If @c true, the socket's synchronous operations will fail with
+   * boost::asio::error::would_block if they are unable to perform the requested
+   * operation immediately. If @c false, synchronous operations will block
+   * until complete.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  void non_blocking(bool mode)
+  {
+    boost::system::error_code ec;
+    this->get_service().non_blocking(this->get_implementation(), mode, ec);
+    boost::asio::detail::throw_error(ec, "non_blocking");
+  }
+
+  /// Sets the non-blocking mode of the socket.
+  /**
+   * @param mode If @c true, the socket's synchronous operations will fail with
+   * boost::asio::error::would_block if they are unable to perform the requested
+   * operation immediately. If @c false, synchronous operations will block
+   * until complete.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  BOOST_ASIO_SYNC_OP_VOID non_blocking(
+      bool mode, boost::system::error_code& ec)
+  {
+    this->get_service().non_blocking(this->get_implementation(), mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the native socket implementation.
+  /**
+   * This function is used to retrieve the non-blocking mode of the underlying
+   * native socket. This mode has no effect on the behaviour of the socket
+   * object's synchronous operations.
+   *
+   * @returns @c true if the underlying socket is in non-blocking mode and
+   * direct system calls may fail with boost::asio::error::would_block (or the
+   * equivalent system error).
+   *
+   * @note The current non-blocking mode is cached by the socket object.
+   * Consequently, the return value may be incorrect if the non-blocking mode
+   * was set directly on the native socket.
+   *
+   * @par Example
+   * This function is intended to allow the encapsulation of arbitrary
+   * non-blocking system calls as asynchronous operations, in a way that is
+   * transparent to the user of the socket object. The following example
+   * illustrates how Linux's @c sendfile system call might be encapsulated:
+   * @code template <typename Handler>
+   * struct sendfile_op
+   * {
+   *   tcp::socket& sock_;
+   *   int fd_;
+   *   Handler handler_;
+   *   off_t offset_;
+   *   std::size_t total_bytes_transferred_;
+   *
+   *   // Function call operator meeting WriteHandler requirements.
+   *   // Used as the handler for the async_write_some operation.
+   *   void operator()(boost::system::error_code ec, std::size_t)
+   *   {
+   *     // Put the underlying socket into non-blocking mode.
+   *     if (!ec)
+   *       if (!sock_.native_non_blocking())
+   *         sock_.native_non_blocking(true, ec);
+   *
+   *     if (!ec)
+   *     {
+   *       for (;;)
+   *       {
+   *         // Try the system call.
+   *         errno = 0;
+   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+   *         ec = boost::system::error_code(n < 0 ? errno : 0,
+   *             boost::asio::error::get_system_category());
+   *         total_bytes_transferred_ += ec ? 0 : n;
+   *
+   *         // Retry operation immediately if interrupted by signal.
+   *         if (ec == boost::asio::error::interrupted)
+   *           continue;
+   *
+   *         // Check if we need to run the operation again.
+   *         if (ec == boost::asio::error::would_block
+   *             || ec == boost::asio::error::try_again)
+   *         {
+   *           // We have to wait for the socket to become ready again.
+   *           sock_.async_wait(tcp::socket::wait_write, *this);
+   *           return;
+   *         }
+   *
+   *         if (ec || n == 0)
+   *         {
+   *           // An error occurred, or we have reached the end of the file.
+   *           // Either way we must exit the loop so we can call the handler.
+   *           break;
+   *         }
+   *
+   *         // Loop around to try calling sendfile again.
+   *       }
+   *     }
+   *
+   *     // Pass result back to user's handler.
+   *     handler_(ec, total_bytes_transferred_);
+   *   }
+   * };
+   *
+   * template <typename Handler>
+   * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+   * {
+   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+   *   sock.async_wait(tcp::socket::wait_write, op);
+   * } @endcode
+   */
+  bool native_non_blocking() const
+  {
+    return this->get_service().native_non_blocking(this->get_implementation());
+  }
+
+  /// Sets the non-blocking mode of the native socket implementation.
+  /**
+   * This function is used to modify the non-blocking mode of the underlying
+   * native socket. It has no effect on the behaviour of the socket object's
+   * synchronous operations.
+   *
+   * @param mode If @c true, the underlying socket is put into non-blocking
+   * mode and direct system calls may fail with boost::asio::error::would_block
+   * (or the equivalent system error).
+   *
+   * @throws boost::system::system_error Thrown on failure. If the @c mode is
+   * @c false, but the current value of @c non_blocking() is @c true, this
+   * function fails with boost::asio::error::invalid_argument, as the
+   * combination does not make sense.
+   *
+   * @par Example
+   * This function is intended to allow the encapsulation of arbitrary
+   * non-blocking system calls as asynchronous operations, in a way that is
+   * transparent to the user of the socket object. The following example
+   * illustrates how Linux's @c sendfile system call might be encapsulated:
+   * @code template <typename Handler>
+   * struct sendfile_op
+   * {
+   *   tcp::socket& sock_;
+   *   int fd_;
+   *   Handler handler_;
+   *   off_t offset_;
+   *   std::size_t total_bytes_transferred_;
+   *
+   *   // Function call operator meeting WriteHandler requirements.
+   *   // Used as the handler for the async_write_some operation.
+   *   void operator()(boost::system::error_code ec, std::size_t)
+   *   {
+   *     // Put the underlying socket into non-blocking mode.
+   *     if (!ec)
+   *       if (!sock_.native_non_blocking())
+   *         sock_.native_non_blocking(true, ec);
+   *
+   *     if (!ec)
+   *     {
+   *       for (;;)
+   *       {
+   *         // Try the system call.
+   *         errno = 0;
+   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+   *         ec = boost::system::error_code(n < 0 ? errno : 0,
+   *             boost::asio::error::get_system_category());
+   *         total_bytes_transferred_ += ec ? 0 : n;
+   *
+   *         // Retry operation immediately if interrupted by signal.
+   *         if (ec == boost::asio::error::interrupted)
+   *           continue;
+   *
+   *         // Check if we need to run the operation again.
+   *         if (ec == boost::asio::error::would_block
+   *             || ec == boost::asio::error::try_again)
+   *         {
+   *           // We have to wait for the socket to become ready again.
+   *           sock_.async_wait(tcp::socket::wait_write, *this);
+   *           return;
+   *         }
+   *
+   *         if (ec || n == 0)
+   *         {
+   *           // An error occurred, or we have reached the end of the file.
+   *           // Either way we must exit the loop so we can call the handler.
+   *           break;
+   *         }
+   *
+   *         // Loop around to try calling sendfile again.
+   *       }
+   *     }
+   *
+   *     // Pass result back to user's handler.
+   *     handler_(ec, total_bytes_transferred_);
+   *   }
+   * };
+   *
+   * template <typename Handler>
+   * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+   * {
+   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+   *   sock.async_wait(tcp::socket::wait_write, op);
+   * } @endcode
+   */
+  void native_non_blocking(bool mode)
+  {
+    boost::system::error_code ec;
+    this->get_service().native_non_blocking(
+        this->get_implementation(), mode, ec);
+    boost::asio::detail::throw_error(ec, "native_non_blocking");
+  }
+
+  /// Sets the non-blocking mode of the native socket implementation.
+  /**
+   * This function is used to modify the non-blocking mode of the underlying
+   * native socket. It has no effect on the behaviour of the socket object's
+   * synchronous operations.
+   *
+   * @param mode If @c true, the underlying socket is put into non-blocking
+   * mode and direct system calls may fail with boost::asio::error::would_block
+   * (or the equivalent system error).
+   *
+   * @param ec Set to indicate what error occurred, if any. If the @c mode is
+   * @c false, but the current value of @c non_blocking() is @c true, this
+   * function fails with boost::asio::error::invalid_argument, as the
+   * combination does not make sense.
+   *
+   * @par Example
+   * This function is intended to allow the encapsulation of arbitrary
+   * non-blocking system calls as asynchronous operations, in a way that is
+   * transparent to the user of the socket object. The following example
+   * illustrates how Linux's @c sendfile system call might be encapsulated:
+   * @code template <typename Handler>
+   * struct sendfile_op
+   * {
+   *   tcp::socket& sock_;
+   *   int fd_;
+   *   Handler handler_;
+   *   off_t offset_;
+   *   std::size_t total_bytes_transferred_;
+   *
+   *   // Function call operator meeting WriteHandler requirements.
+   *   // Used as the handler for the async_write_some operation.
+   *   void operator()(boost::system::error_code ec, std::size_t)
+   *   {
+   *     // Put the underlying socket into non-blocking mode.
+   *     if (!ec)
+   *       if (!sock_.native_non_blocking())
+   *         sock_.native_non_blocking(true, ec);
+   *
+   *     if (!ec)
+   *     {
+   *       for (;;)
+   *       {
+   *         // Try the system call.
+   *         errno = 0;
+   *         int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
+   *         ec = boost::system::error_code(n < 0 ? errno : 0,
+   *             boost::asio::error::get_system_category());
+   *         total_bytes_transferred_ += ec ? 0 : n;
+   *
+   *         // Retry operation immediately if interrupted by signal.
+   *         if (ec == boost::asio::error::interrupted)
+   *           continue;
+   *
+   *         // Check if we need to run the operation again.
+   *         if (ec == boost::asio::error::would_block
+   *             || ec == boost::asio::error::try_again)
+   *         {
+   *           // We have to wait for the socket to become ready again.
+   *           sock_.async_wait(tcp::socket::wait_write, *this);
+   *           return;
+   *         }
+   *
+   *         if (ec || n == 0)
+   *         {
+   *           // An error occurred, or we have reached the end of the file.
+   *           // Either way we must exit the loop so we can call the handler.
+   *           break;
+   *         }
+   *
+   *         // Loop around to try calling sendfile again.
+   *       }
+   *     }
+   *
+   *     // Pass result back to user's handler.
+   *     handler_(ec, total_bytes_transferred_);
+   *   }
+   * };
+   *
+   * template <typename Handler>
+   * void async_sendfile(tcp::socket& sock, int fd, Handler h)
+   * {
+   *   sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
+   *   sock.async_wait(tcp::socket::wait_write, op);
+   * } @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
+      bool mode, boost::system::error_code& ec)
+  {
+    this->get_service().native_non_blocking(
+        this->get_implementation(), mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get the local endpoint of the socket.
+  /**
+   * This function is used to obtain the locally bound endpoint of the socket.
+   *
+   * @returns An object that represents the local endpoint of the socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
+   * @endcode
+   */
+  endpoint_type local_endpoint() const
+  {
+    boost::system::error_code ec;
+    endpoint_type ep = this->get_service().local_endpoint(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "local_endpoint");
+    return ep;
+  }
+
+  /// Get the local endpoint of the socket.
+  /**
+   * This function is used to obtain the locally bound endpoint of the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns An object that represents the local endpoint of the socket.
+   * Returns a default-constructed endpoint object if an error occurred.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  endpoint_type local_endpoint(boost::system::error_code& ec) const
+  {
+    return this->get_service().local_endpoint(this->get_implementation(), ec);
+  }
+
+  /// Get the remote endpoint of the socket.
+  /**
+   * This function is used to obtain the remote endpoint of the socket.
+   *
+   * @returns An object that represents the remote endpoint of the socket.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
+   * @endcode
+   */
+  endpoint_type remote_endpoint() const
+  {
+    boost::system::error_code ec;
+    endpoint_type ep = this->get_service().remote_endpoint(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "remote_endpoint");
+    return ep;
+  }
+
+  /// Get the remote endpoint of the socket.
+  /**
+   * This function is used to obtain the remote endpoint of the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns An object that represents the remote endpoint of the socket.
+   * Returns a default-constructed endpoint object if an error occurred.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  endpoint_type remote_endpoint(boost::system::error_code& ec) const
+  {
+    return this->get_service().remote_endpoint(this->get_implementation(), ec);
+  }
+
+  /// Disable sends or receives on the socket.
+  /**
+   * This function is used to disable send operations, receive operations, or
+   * both.
+   *
+   * @param what Determines what types of operation will no longer be allowed.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * Shutting down the send side of the socket:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
+   * @endcode
+   */
+  void shutdown(shutdown_type what)
+  {
+    boost::system::error_code ec;
+    this->get_service().shutdown(this->get_implementation(), what, ec);
+    boost::asio::detail::throw_error(ec, "shutdown");
+  }
+
+  /// Disable sends or receives on the socket.
+  /**
+   * This function is used to disable send operations, receive operations, or
+   * both.
+   *
+   * @param what Determines what types of operation will no longer be allowed.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * Shutting down the send side of the socket:
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
+      boost::system::error_code& ec)
+  {
+    this->get_service().shutdown(this->get_implementation(), what, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Wait for the socket to become ready to read, ready to write, or to have
+  /// pending error conditions.
+  /**
+   * This function is used to perform a blocking wait for a socket to enter
+   * a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired socket state.
+   *
+   * @par Example
+   * Waiting for a socket to become readable.
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * socket.wait(boost::asio::ip::tcp::socket::wait_read);
+   * @endcode
+   */
+  void wait(wait_type w)
+  {
+    boost::system::error_code ec;
+    this->get_service().wait(this->get_implementation(), w, ec);
+    boost::asio::detail::throw_error(ec, "wait");
+  }
+
+  /// Wait for the socket to become ready to read, ready to write, or to have
+  /// pending error conditions.
+  /**
+   * This function is used to perform a blocking wait for a socket to enter
+   * a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired socket state.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * Waiting for a socket to become readable.
+   * @code
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+  {
+    this->get_service().wait(this->get_implementation(), w, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Asynchronously wait for the socket to become ready to read, ready to
+  /// write, or to have pending error conditions.
+  /**
+   * This function is used to perform an asynchronous wait for a socket to enter
+   * a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired socket state.
+   *
+   * @param handler The handler to be called when the wait operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void wait_handler(const boost::system::error_code& error)
+   * {
+   *   if (!error)
+   *   {
+   *     // Wait succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * ...
+   * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
+   * @endcode
+   */
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WaitHandler.
+    BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_wait(this->get_implementation(),
+        w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_wait(this->get_implementation(),
+        w, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+protected:
+  /// Protected destructor to prevent deletion through this type.
+  /**
+   * This function destroys the socket, cancelling any outstanding asynchronous
+   * operations associated with the socket as if by calling @c cancel.
+   */
+  ~basic_socket()
+  {
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
+  basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_BASIC_SOCKET_HPP

+ 1988 - 0
cpir-read/boost/boost/asio/basic_socket_acceptor.hpp

@@ -0,0 +1,1988 @@
+//
+// basic_socket_acceptor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
+#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/socket_base.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/socket_acceptor_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#  include <boost/asio/detail/null_socket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::null_socket_service<Protocol>
+# elif defined(BOOST_ASIO_HAS_IOCP)
+#  include <boost/asio/detail/win_iocp_socket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
+# else
+#  include <boost/asio/detail/reactive_socket_service.hpp>
+#  define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
+# endif
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides the ability to accept new connections.
+/**
+ * The basic_socket_acceptor class template is used for accepting new socket
+ * connections.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Example
+ * Opening a socket acceptor with the SO_REUSEADDR option enabled:
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
+ * acceptor.open(endpoint.protocol());
+ * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ * acceptor.bind(endpoint);
+ * acceptor.listen();
+ * @endcode
+ */
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
+class basic_socket_acceptor
+  : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
+    public socket_base
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef io_context::executor_type executor_type;
+
+  /// The native representation of an acceptor.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct an acceptor without opening it.
+  /**
+   * This constructor creates an acceptor without opening it to listen for new
+   * connections. The open() function must be called before the acceptor can
+   * accept new socket connections.
+   *
+   * @param io_context The io_context object that the acceptor will use to
+   * dispatch handlers for any asynchronous operations performed on the
+   * acceptor.
+   */
+  explicit basic_socket_acceptor(boost::asio::io_context& io_context)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+  }
+
+  /// Construct an open acceptor.
+  /**
+   * This constructor creates an acceptor and automatically opens it.
+   *
+   * @param io_context The io_context object that the acceptor will use to
+   * dispatch handlers for any asynchronous operations performed on the
+   * acceptor.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_socket_acceptor(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Construct an acceptor opened on the given endpoint.
+  /**
+   * This constructor creates an acceptor and automatically opens it to listen
+   * for new connections on the specified endpoint.
+   *
+   * @param io_context The io_context object that the acceptor will use to
+   * dispatch handlers for any asynchronous operations performed on the
+   * acceptor.
+   *
+   * @param endpoint An endpoint on the local machine on which the acceptor
+   * will listen for new connections.
+   *
+   * @param reuse_addr Whether the constructor should set the socket option
+   * socket_base::reuse_address.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note This constructor is equivalent to the following code:
+   * @code
+   * basic_socket_acceptor<Protocol> acceptor(io_context);
+   * acceptor.open(endpoint.protocol());
+   * if (reuse_addr)
+   *   acceptor.set_option(socket_base::reuse_address(true));
+   * acceptor.bind(endpoint);
+   * acceptor.listen(listen_backlog);
+   * @endcode
+   */
+  basic_socket_acceptor(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint, bool reuse_addr = true)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    const protocol_type protocol = endpoint.protocol();
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+    if (reuse_addr)
+    {
+      this->get_service().set_option(this->get_implementation(),
+          socket_base::reuse_address(true), ec);
+      boost::asio::detail::throw_error(ec, "set_option");
+    }
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    boost::asio::detail::throw_error(ec, "bind");
+    this->get_service().listen(this->get_implementation(),
+        socket_base::max_listen_connections, ec);
+    boost::asio::detail::throw_error(ec, "listen");
+  }
+
+  /// Construct a basic_socket_acceptor on an existing native acceptor.
+  /**
+   * This constructor creates an acceptor object to hold an existing native
+   * acceptor.
+   *
+   * @param io_context The io_context object that the acceptor will use to
+   * dispatch handlers for any asynchronous operations performed on the
+   * acceptor.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_acceptor A native acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_socket_acceptor(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_acceptor)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_acceptor, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_socket_acceptor from another.
+  /**
+   * This constructor moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket_acceptor(io_context&) constructor.
+   */
+  basic_socket_acceptor(basic_socket_acceptor&& other)
+    : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_socket_acceptor from another.
+  /**
+   * This assignment operator moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket_acceptor(io_context&) constructor.
+   */
+  basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
+  {
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+    return *this;
+  }
+
+  // All socket acceptors have access to each other's implementations.
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  friend class basic_socket_acceptor;
+
+  /// Move-construct a basic_socket_acceptor from an acceptor of another
+  /// protocol type.
+  /**
+   * This constructor moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_socket_acceptor(
+      basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_io_object<BOOST_ASIO_SVC_T>(
+        other.get_service(), other.get_implementation())
+  {
+  }
+
+  /// Move-assign a basic_socket_acceptor from an acceptor of another protocol
+  /// type.
+  /**
+   * This assignment operator moves an acceptor from one object to another.
+   *
+   * @param other The other basic_socket_acceptor object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_socket_acceptor>::type& operator=(
+        basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket_acceptor tmp(std::move(other));
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the acceptor.
+  /**
+   * This function destroys the acceptor, cancelling any outstanding
+   * asynchronous operations associated with the acceptor as if by calling
+   * @c cancel.
+   */
+  ~basic_socket_acceptor()
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_context()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_service()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+  }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+  /// Open the acceptor using the specified protocol.
+  /**
+   * This function opens the socket acceptor so that it will use the specified
+   * protocol.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * acceptor.open(boost::asio::ip::tcp::v4());
+   * @endcode
+   */
+  void open(const protocol_type& protocol = protocol_type())
+  {
+    boost::system::error_code ec;
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    boost::asio::detail::throw_error(ec, "open");
+  }
+
+  /// Open the acceptor using the specified protocol.
+  /**
+   * This function opens the socket acceptor so that it will use the specified
+   * protocol.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * boost::system::error_code ec;
+   * acceptor.open(boost::asio::ip::tcp::v4(), ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
+      boost::system::error_code& ec)
+  {
+    this->get_service().open(this->get_implementation(), protocol, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Assigns an existing native acceptor to the acceptor.
+  /*
+   * This function opens the acceptor to hold an existing native acceptor.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param native_acceptor A native acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void assign(const protocol_type& protocol,
+      const native_handle_type& native_acceptor)
+  {
+    boost::system::error_code ec;
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_acceptor, ec);
+    boost::asio::detail::throw_error(ec, "assign");
+  }
+
+  /// Assigns an existing native acceptor to the acceptor.
+  /*
+   * This function opens the acceptor to hold an existing native acceptor.
+   *
+   * @param protocol An object specifying which protocol is to be used.
+   *
+   * @param native_acceptor A native acceptor.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
+      const native_handle_type& native_acceptor, boost::system::error_code& ec)
+  {
+    this->get_service().assign(this->get_implementation(),
+        protocol, native_acceptor, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the acceptor is open.
+  bool is_open() const
+  {
+    return this->get_service().is_open(this->get_implementation());
+  }
+
+  /// Bind the acceptor to the given local endpoint.
+  /**
+   * This function binds the socket acceptor to the specified endpoint on the
+   * local machine.
+   *
+   * @param endpoint An endpoint on the local machine to which the socket
+   * acceptor will be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
+   * acceptor.open(endpoint.protocol());
+   * acceptor.bind(endpoint);
+   * @endcode
+   */
+  void bind(const endpoint_type& endpoint)
+  {
+    boost::system::error_code ec;
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    boost::asio::detail::throw_error(ec, "bind");
+  }
+
+  /// Bind the acceptor to the given local endpoint.
+  /**
+   * This function binds the socket acceptor to the specified endpoint on the
+   * local machine.
+   *
+   * @param endpoint An endpoint on the local machine to which the socket
+   * acceptor will be bound.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
+   * acceptor.open(endpoint.protocol());
+   * boost::system::error_code ec;
+   * acceptor.bind(endpoint, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
+      boost::system::error_code& ec)
+  {
+    this->get_service().bind(this->get_implementation(), endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Place the acceptor into the state where it will listen for new
+  /// connections.
+  /**
+   * This function puts the socket acceptor into the state where it may accept
+   * new connections.
+   *
+   * @param backlog The maximum length of the queue of pending connections.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void listen(int backlog = socket_base::max_listen_connections)
+  {
+    boost::system::error_code ec;
+    this->get_service().listen(this->get_implementation(), backlog, ec);
+    boost::asio::detail::throw_error(ec, "listen");
+  }
+
+  /// Place the acceptor into the state where it will listen for new
+  /// connections.
+  /**
+   * This function puts the socket acceptor into the state where it may accept
+   * new connections.
+   *
+   * @param backlog The maximum length of the queue of pending connections.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec)
+  {
+    this->get_service().listen(this->get_implementation(), backlog, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Close the acceptor.
+  /**
+   * This function is used to close the acceptor. Any asynchronous accept
+   * operations will be cancelled immediately.
+   *
+   * A subsequent call to open() is required before the acceptor can again be
+   * used to again perform socket accept operations.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void close()
+  {
+    boost::system::error_code ec;
+    this->get_service().close(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "close");
+  }
+
+  /// Close the acceptor.
+  /**
+   * This function is used to close the acceptor. Any asynchronous accept
+   * operations will be cancelled immediately.
+   *
+   * A subsequent call to open() is required before the acceptor can again be
+   * used to again perform socket accept operations.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * acceptor.close(ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    this->get_service().close(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Release ownership of the underlying native acceptor.
+  /**
+   * This function causes all outstanding asynchronous accept operations to
+   * finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error. Ownership of the
+   * native acceptor is then transferred to the caller.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note This function is unsupported on Windows versions prior to Windows
+   * 8.1, and will fail with boost::asio::error::operation_not_supported on
+   * these platforms.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+  __declspec(deprecated("This function always fails with "
+        "operation_not_supported when used on Windows versions "
+        "prior to Windows 8.1."))
+#endif
+  native_handle_type release()
+  {
+    boost::system::error_code ec;
+    native_handle_type s = this->get_service().release(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "release");
+    return s;
+  }
+
+  /// Release ownership of the underlying native acceptor.
+  /**
+   * This function causes all outstanding asynchronous accept operations to
+   * finish immediately, and the handlers for cancelled operations will be
+   * passed the boost::asio::error::operation_aborted error. Ownership of the
+   * native acceptor is then transferred to the caller.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note This function is unsupported on Windows versions prior to Windows
+   * 8.1, and will fail with boost::asio::error::operation_not_supported on
+   * these platforms.
+   */
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \
+  && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
+  __declspec(deprecated("This function always fails with "
+        "operation_not_supported when used on Windows versions "
+        "prior to Windows 8.1."))
+#endif
+  native_handle_type release(boost::system::error_code& ec)
+  {
+    return this->get_service().release(this->get_implementation(), ec);
+  }
+
+  /// Get the native acceptor representation.
+  /**
+   * This function may be used to obtain the underlying representation of the
+   * acceptor. This is intended to allow access to native acceptor functionality
+   * that is not otherwise provided.
+   */
+  native_handle_type native_handle()
+  {
+    return this->get_service().native_handle(this->get_implementation());
+  }
+
+  /// Cancel all asynchronous operations associated with the acceptor.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void cancel()
+  {
+    boost::system::error_code ec;
+    this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+  }
+
+  /// Cancel all asynchronous operations associated with the acceptor.
+  /**
+   * This function causes all outstanding asynchronous connect, send and receive
+   * operations to finish immediately, and the handlers for cancelled operations
+   * will be passed the boost::asio::error::operation_aborted error.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+  {
+    this->get_service().cancel(this->get_implementation(), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Set an option on the acceptor.
+  /**
+   * This function is used to set an option on the acceptor.
+   *
+   * @param option The new option value to be set on the acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa SettableSocketOption @n
+   * boost::asio::socket_base::reuse_address
+   * boost::asio::socket_base::enable_connection_aborted
+   *
+   * @par Example
+   * Setting the SOL_SOCKET/SO_REUSEADDR option:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::reuse_address option(true);
+   * acceptor.set_option(option);
+   * @endcode
+   */
+  template <typename SettableSocketOption>
+  void set_option(const SettableSocketOption& option)
+  {
+    boost::system::error_code ec;
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "set_option");
+  }
+
+  /// Set an option on the acceptor.
+  /**
+   * This function is used to set an option on the acceptor.
+   *
+   * @param option The new option value to be set on the acceptor.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa SettableSocketOption @n
+   * boost::asio::socket_base::reuse_address
+   * boost::asio::socket_base::enable_connection_aborted
+   *
+   * @par Example
+   * Setting the SOL_SOCKET/SO_REUSEADDR option:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::reuse_address option(true);
+   * boost::system::error_code ec;
+   * acceptor.set_option(option, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  template <typename SettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
+      boost::system::error_code& ec)
+  {
+    this->get_service().set_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get an option from the acceptor.
+  /**
+   * This function is used to get the current value of an option on the
+   * acceptor.
+   *
+   * @param option The option value to be obtained from the acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa GettableSocketOption @n
+   * boost::asio::socket_base::reuse_address
+   *
+   * @par Example
+   * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::reuse_address option;
+   * acceptor.get_option(option);
+   * bool is_set = option.get();
+   * @endcode
+   */
+  template <typename GettableSocketOption>
+  void get_option(GettableSocketOption& option) const
+  {
+    boost::system::error_code ec;
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    boost::asio::detail::throw_error(ec, "get_option");
+  }
+
+  /// Get an option from the acceptor.
+  /**
+   * This function is used to get the current value of an option on the
+   * acceptor.
+   *
+   * @param option The option value to be obtained from the acceptor.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa GettableSocketOption @n
+   * boost::asio::socket_base::reuse_address
+   *
+   * @par Example
+   * Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::reuse_address option;
+   * boost::system::error_code ec;
+   * acceptor.get_option(option, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * bool is_set = option.get();
+   * @endcode
+   */
+  template <typename GettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
+      boost::system::error_code& ec) const
+  {
+    this->get_service().get_option(this->get_implementation(), option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Perform an IO control command on the acceptor.
+  /**
+   * This function is used to execute an IO control command on the acceptor.
+   *
+   * @param command The IO control command to be performed on the acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @sa IoControlCommand @n
+   * boost::asio::socket_base::non_blocking_io
+   *
+   * @par Example
+   * Getting the number of bytes ready to read:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
+   * socket.io_control(command);
+   * @endcode
+   */
+  template <typename IoControlCommand>
+  void io_control(IoControlCommand& command)
+  {
+    boost::system::error_code ec;
+    this->get_service().io_control(this->get_implementation(), command, ec);
+    boost::asio::detail::throw_error(ec, "io_control");
+  }
+
+  /// Perform an IO control command on the acceptor.
+  /**
+   * This function is used to execute an IO control command on the acceptor.
+   *
+   * @param command The IO control command to be performed on the acceptor.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @sa IoControlCommand @n
+   * boost::asio::socket_base::non_blocking_io
+   *
+   * @par Example
+   * Getting the number of bytes ready to read:
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
+   * boost::system::error_code ec;
+   * socket.io_control(command, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  template <typename IoControlCommand>
+  BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
+      boost::system::error_code& ec)
+  {
+    this->get_service().io_control(this->get_implementation(), command, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the acceptor.
+  /**
+   * @returns @c true if the acceptor's synchronous operations will fail with
+   * boost::asio::error::would_block if they are unable to perform the requested
+   * operation immediately. If @c false, synchronous operations will block
+   * until complete.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  bool non_blocking() const
+  {
+    return this->get_service().non_blocking(this->get_implementation());
+  }
+
+  /// Sets the non-blocking mode of the acceptor.
+  /**
+   * @param mode If @c true, the acceptor's synchronous operations will fail
+   * with boost::asio::error::would_block if they are unable to perform the
+   * requested operation immediately. If @c false, synchronous operations will
+   * block until complete.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  void non_blocking(bool mode)
+  {
+    boost::system::error_code ec;
+    this->get_service().non_blocking(this->get_implementation(), mode, ec);
+    boost::asio::detail::throw_error(ec, "non_blocking");
+  }
+
+  /// Sets the non-blocking mode of the acceptor.
+  /**
+   * @param mode If @c true, the acceptor's synchronous operations will fail
+   * with boost::asio::error::would_block if they are unable to perform the
+   * requested operation immediately. If @c false, synchronous operations will
+   * block until complete.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @note The non-blocking mode has no effect on the behaviour of asynchronous
+   * operations. Asynchronous operations will never fail with the error
+   * boost::asio::error::would_block.
+   */
+  BOOST_ASIO_SYNC_OP_VOID non_blocking(
+      bool mode, boost::system::error_code& ec)
+  {
+    this->get_service().non_blocking(this->get_implementation(), mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the native acceptor implementation.
+  /**
+   * This function is used to retrieve the non-blocking mode of the underlying
+   * native acceptor. This mode has no effect on the behaviour of the acceptor
+   * object's synchronous operations.
+   *
+   * @returns @c true if the underlying acceptor is in non-blocking mode and
+   * direct system calls may fail with boost::asio::error::would_block (or the
+   * equivalent system error).
+   *
+   * @note The current non-blocking mode is cached by the acceptor object.
+   * Consequently, the return value may be incorrect if the non-blocking mode
+   * was set directly on the native acceptor.
+   */
+  bool native_non_blocking() const
+  {
+    return this->get_service().native_non_blocking(this->get_implementation());
+  }
+
+  /// Sets the non-blocking mode of the native acceptor implementation.
+  /**
+   * This function is used to modify the non-blocking mode of the underlying
+   * native acceptor. It has no effect on the behaviour of the acceptor object's
+   * synchronous operations.
+   *
+   * @param mode If @c true, the underlying acceptor is put into non-blocking
+   * mode and direct system calls may fail with boost::asio::error::would_block
+   * (or the equivalent system error).
+   *
+   * @throws boost::system::system_error Thrown on failure. If the @c mode is
+   * @c false, but the current value of @c non_blocking() is @c true, this
+   * function fails with boost::asio::error::invalid_argument, as the
+   * combination does not make sense.
+   */
+  void native_non_blocking(bool mode)
+  {
+    boost::system::error_code ec;
+    this->get_service().native_non_blocking(
+        this->get_implementation(), mode, ec);
+    boost::asio::detail::throw_error(ec, "native_non_blocking");
+  }
+
+  /// Sets the non-blocking mode of the native acceptor implementation.
+  /**
+   * This function is used to modify the non-blocking mode of the underlying
+   * native acceptor. It has no effect on the behaviour of the acceptor object's
+   * synchronous operations.
+   *
+   * @param mode If @c true, the underlying acceptor is put into non-blocking
+   * mode and direct system calls may fail with boost::asio::error::would_block
+   * (or the equivalent system error).
+   *
+   * @param ec Set to indicate what error occurred, if any. If the @c mode is
+   * @c false, but the current value of @c non_blocking() is @c true, this
+   * function fails with boost::asio::error::invalid_argument, as the
+   * combination does not make sense.
+   */
+  BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
+      bool mode, boost::system::error_code& ec)
+  {
+    this->get_service().native_non_blocking(
+        this->get_implementation(), mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get the local endpoint of the acceptor.
+  /**
+   * This function is used to obtain the locally bound endpoint of the acceptor.
+   *
+   * @returns An object that represents the local endpoint of the acceptor.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
+   * @endcode
+   */
+  endpoint_type local_endpoint() const
+  {
+    boost::system::error_code ec;
+    endpoint_type ep = this->get_service().local_endpoint(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "local_endpoint");
+    return ep;
+  }
+
+  /// Get the local endpoint of the acceptor.
+  /**
+   * This function is used to obtain the locally bound endpoint of the acceptor.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns An object that represents the local endpoint of the acceptor.
+   * Returns a default-constructed endpoint object if an error occurred and the
+   * error handler did not throw an exception.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  endpoint_type local_endpoint(boost::system::error_code& ec) const
+  {
+    return this->get_service().local_endpoint(this->get_implementation(), ec);
+  }
+
+  /// Wait for the acceptor to become ready to read, ready to write, or to have
+  /// pending error conditions.
+  /**
+   * This function is used to perform a blocking wait for an acceptor to enter
+   * a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired acceptor state.
+   *
+   * @par Example
+   * Waiting for an acceptor to become readable.
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read);
+   * @endcode
+   */
+  void wait(wait_type w)
+  {
+    boost::system::error_code ec;
+    this->get_service().wait(this->get_implementation(), w, ec);
+    boost::asio::detail::throw_error(ec, "wait");
+  }
+
+  /// Wait for the acceptor to become ready to read, ready to write, or to have
+  /// pending error conditions.
+  /**
+   * This function is used to perform a blocking wait for an acceptor to enter
+   * a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired acceptor state.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * Waiting for an acceptor to become readable.
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::system::error_code ec;
+   * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
+   * @endcode
+   */
+  BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
+  {
+    this->get_service().wait(this->get_implementation(), w, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Asynchronously wait for the acceptor to become ready to read, ready to
+  /// write, or to have pending error conditions.
+  /**
+   * This function is used to perform an asynchronous wait for an acceptor to
+   * enter a ready to read, write or error condition state.
+   *
+   * @param w Specifies the desired acceptor state.
+   *
+   * @param handler The handler to be called when the wait operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void wait_handler(const boost::system::error_code& error)
+   * {
+   *   if (!error)
+   *   {
+   *     // Wait succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * acceptor.async_wait(
+   *     boost::asio::ip::tcp::acceptor::wait_read,
+   *     wait_handler);
+   * @endcode
+   */
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WaitHandler.
+    BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_wait(this->get_implementation(),
+        w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_wait(this->get_implementation(),
+        w, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer into the
+   * given socket. The function call will block until a new connection has been
+   * accepted successfully or an error occurs.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * acceptor.accept(socket);
+   * @endcode
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1, typename SocketService>
+  void accept(basic_socket<Protocol1, SocketService>& peer,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1>
+  void accept(basic_socket<Protocol1>& peer,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    boost::system::error_code ec;
+    this->get_service().accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0), ec);
+    boost::asio::detail::throw_error(ec, "accept");
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer into the
+   * given socket. The function call will block until a new connection has been
+   * accepted successfully or an error occurs.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::system::error_code ec;
+   * acceptor.accept(socket, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1, typename SocketService>
+  BOOST_ASIO_SYNC_OP_VOID accept(
+      basic_socket<Protocol1, SocketService>& peer,
+      boost::system::error_code& ec,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1>
+  BOOST_ASIO_SYNC_OP_VOID accept(
+      basic_socket<Protocol1>& peer, boost::system::error_code& ec,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    this->get_service().accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0), ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection into a
+   * socket. The function call always returns immediately.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   * Ownership of the peer object is retained by the caller, which must
+   * guarantee that it is valid until the handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const boost::system::error_code& error)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * acceptor.async_accept(socket, accept_handler);
+   * @endcode
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1, typename SocketService, typename AcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+      void (boost::system::error_code))
+  async_accept(basic_socket<Protocol1, SocketService>& peer,
+      BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename Protocol1, typename AcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+      void (boost::system::error_code))
+  async_accept(basic_socket<Protocol1>& peer,
+      BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+      typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a AcceptHandler.
+    BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0),
+        BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<AcceptHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_accept(this->get_implementation(),
+        peer, static_cast<endpoint_type*>(0), init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Accept a new connection and obtain the endpoint of the peer
+  /**
+   * This function is used to accept a new connection from a peer into the
+   * given socket, and additionally provide the endpoint of the remote peer.
+   * The function call will block until a new connection has been accepted
+   * successfully or an error occurs.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   *
+   * @param peer_endpoint An endpoint object which will receive the endpoint of
+   * the remote peer.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * acceptor.accept(socket, endpoint);
+   * @endcode
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename SocketService>
+  void accept(basic_socket<protocol_type, SocketService>& peer,
+      endpoint_type& peer_endpoint)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  void accept(basic_socket<protocol_type>& peer, endpoint_type& peer_endpoint)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    boost::system::error_code ec;
+    this->get_service().accept(this->get_implementation(),
+        peer, &peer_endpoint, ec);
+    boost::asio::detail::throw_error(ec, "accept");
+  }
+
+  /// Accept a new connection and obtain the endpoint of the peer
+  /**
+   * This function is used to accept a new connection from a peer into the
+   * given socket, and additionally provide the endpoint of the remote peer.
+   * The function call will block until a new connection has been accepted
+   * successfully or an error occurs.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   *
+   * @param peer_endpoint An endpoint object which will receive the endpoint of
+   * the remote peer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(io_context);
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * boost::system::error_code ec;
+   * acceptor.accept(socket, endpoint, ec);
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename SocketService>
+  BOOST_ASIO_SYNC_OP_VOID accept(
+      basic_socket<protocol_type, SocketService>& peer,
+      endpoint_type& peer_endpoint, boost::system::error_code& ec)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
+      endpoint_type& peer_endpoint, boost::system::error_code& ec)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    this->get_service().accept(
+        this->get_implementation(), peer, &peer_endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection into a
+   * socket, and additionally obtain the endpoint of the remote peer. The
+   * function call always returns immediately.
+   *
+   * @param peer The socket into which the new connection will be accepted.
+   * Ownership of the peer object is retained by the caller, which must
+   * guarantee that it is valid until the handler is called.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written. Ownership of the peer_endpoint object is
+   * retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename SocketService, typename AcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+      void (boost::system::error_code))
+  async_accept(basic_socket<protocol_type, SocketService>& peer,
+      endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  template <typename AcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
+      void (boost::system::error_code))
+  async_accept(basic_socket<protocol_type>& peer,
+      endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a AcceptHandler.
+    BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(this->get_implementation(), peer,
+        &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<AcceptHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_accept(this->get_implementation(),
+        peer, &peer_endpoint, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(acceptor.accept());
+   * @endcode
+   */
+  typename Protocol::socket accept()
+  {
+    boost::system::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(
+          this->get_implementation(), 0, 0, ec));
+    boost::asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(boost::system::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(), 0, 0, ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const boost::system::error_code& error,
+   *     boost::asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * acceptor.async_accept(accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (boost::system::error_code, typename Protocol::socket))
+  async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(
+        this->get_implementation(), static_cast<boost::asio::io_context*>(0),
+        static_cast<endpoint_type*>(0),
+        BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<MoveAcceptHandler,
+      void (boost::system::error_code,
+        typename Protocol::socket)> init(handler);
+
+    this->get_service().async_accept(
+        this->get_implementation(), static_cast<boost::asio::io_context*>(0),
+        static_cast<endpoint_type*>(0), init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(acceptor.accept());
+   * @endcode
+   */
+  typename Protocol::socket accept(boost::asio::io_context& io_context)
+  {
+    boost::system::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          &io_context, static_cast<endpoint_type*>(0), ec));
+    boost::asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      boost::asio::io_context& io_context, boost::system::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        &io_context, static_cast<endpoint_type*>(0), ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const boost::system::error_code& error,
+   *     boost::asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * acceptor.async_accept(io_context2, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (boost::system::error_code, typename Protocol::socket))
+  async_accept(boost::asio::io_context& io_context,
+      BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(this->get_implementation(),
+        &io_context, static_cast<endpoint_type*>(0),
+        BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<MoveAcceptHandler,
+      void (boost::system::error_code,
+        typename Protocol::socket)> init(handler);
+
+    this->get_service().async_accept(this->get_implementation(),
+        &io_context, static_cast<endpoint_type*>(0), init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
+   * @endcode
+   */
+  typename Protocol::socket accept(endpoint_type& peer_endpoint)
+  {
+    boost::system::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec));
+    boost::asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      endpoint_type& peer_endpoint, boost::system::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written. Ownership of the peer_endpoint object is
+   * retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const boost::system::error_code& error,
+   *     boost::asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * acceptor.async_accept(endpoint, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (boost::system::error_code, typename Protocol::socket))
+  async_accept(endpoint_type& peer_endpoint,
+      BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(this->get_implementation(),
+        static_cast<boost::asio::io_context*>(0), &peer_endpoint,
+        BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<MoveAcceptHandler,
+      void (boost::system::error_code,
+        typename Protocol::socket)> init(handler);
+
+    this->get_service().async_accept(this->get_implementation(),
+        static_cast<boost::asio::io_context*>(0), &peer_endpoint,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @returns A socket object representing the newly accepted connection.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * boost::asio::ip::tcp::socket socket(
+   *     acceptor.accept(io_context2, endpoint));
+   * @endcode
+   */
+  typename Protocol::socket accept(
+      boost::asio::io_context& io_context, endpoint_type& peer_endpoint)
+  {
+    boost::system::error_code ec;
+    typename Protocol::socket peer(
+        this->get_service().accept(this->get_implementation(),
+          &io_context, &peer_endpoint, ec));
+    boost::asio::detail::throw_error(ec, "accept");
+    return peer;
+  }
+
+  /// Accept a new connection.
+  /**
+   * This function is used to accept a new connection from a peer. The function
+   * call will block until a new connection has been accepted successfully or
+   * an error occurs.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns On success, a socket object representing the newly accepted
+   * connection. On error, a socket object where is_open() is false.
+   *
+   * @par Example
+   * @code
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * boost::asio::ip::tcp::socket socket(
+   *     acceptor.accept(io_context2, endpoint, ec));
+   * if (ec)
+   * {
+   *   // An error occurred.
+   * }
+   * @endcode
+   */
+  typename Protocol::socket accept(boost::asio::io_context& io_context,
+      endpoint_type& peer_endpoint, boost::system::error_code& ec)
+  {
+    return this->get_service().accept(this->get_implementation(),
+        &io_context, &peer_endpoint, ec);
+  }
+
+  /// Start an asynchronous accept.
+  /**
+   * This function is used to asynchronously accept a new connection. The
+   * function call always returns immediately.
+   *
+   * This overload requires that the Protocol template parameter satisfy the
+   * AcceptableProtocol type requirements.
+   *
+   * @param io_context The io_context object to be used for the newly accepted
+   * socket.
+   *
+   * @param peer_endpoint An endpoint object into which the endpoint of the
+   * remote peer will be written. Ownership of the peer_endpoint object is
+   * retained by the caller, which must guarantee that it is valid until the
+   * handler is called.
+   *
+   * @param handler The handler to be called when the accept operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   typename Protocol::socket peer // On success, the newly accepted socket.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @par Example
+   * @code
+   * void accept_handler(const boost::system::error_code& error,
+   *     boost::asio::ip::tcp::socket peer)
+   * {
+   *   if (!error)
+   *   {
+   *     // Accept succeeded.
+   *   }
+   * }
+   *
+   * ...
+   *
+   * boost::asio::ip::tcp::acceptor acceptor(io_context);
+   * ...
+   * boost::asio::ip::tcp::endpoint endpoint;
+   * acceptor.async_accept(io_context2, endpoint, accept_handler);
+   * @endcode
+   */
+  template <typename MoveAcceptHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+      void (boost::system::error_code, typename Protocol::socket))
+  async_accept(boost::asio::io_context& io_context,
+      endpoint_type& peer_endpoint,
+      BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a MoveAcceptHandler.
+    BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
+        handler, typename Protocol::socket) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_accept(
+        this->get_implementation(), &io_context, &peer_endpoint,
+        BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<MoveAcceptHandler,
+      void (boost::system::error_code,
+        typename Protocol::socket)> init(handler);
+
+    this->get_service().async_accept(this->get_implementation(),
+        &io_context, &peer_endpoint, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP

+ 432 - 0
cpir-read/boost/boost/asio/basic_socket_iostream.hpp

@@ -0,0 +1,432 @@
+//
+// basic_socket_iostream.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
+#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#include <istream>
+#include <ostream>
+#include <boost/asio/basic_socket_streambuf.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+# include <boost/asio/detail/variadic_templates.hpp>
+
+// A macro that should expand to:
+//   template <typename T1, ..., typename Tn>
+//   explicit basic_socket_iostream(T1 x1, ..., Tn xn)
+//     : std::basic_iostream<char>(
+//         &this->detail::socket_iostream_base<
+//           Protocol BOOST_ASIO_SVC_TARG, Clock,
+//           WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+//   {
+//     if (rdbuf()->connect(x1, ..., xn) == 0)
+//       this->setstate(std::ios_base::failbit);
+//   }
+// This macro should only persist within this file.
+
+# define BOOST_ASIO_PRIVATE_CTR_DEF(n) \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
+    : std::basic_iostream<char>( \
+        &this->detail::socket_iostream_base< \
+          Protocol BOOST_ASIO_SVC_TARG, Clock, \
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_) \
+  { \
+    this->setf(std::ios_base::unitbuf); \
+    if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
+      this->setstate(std::ios_base::failbit); \
+  } \
+  /**/
+
+// A macro that should expand to:
+//   template <typename T1, ..., typename Tn>
+//   void connect(T1 x1, ..., Tn xn)
+//   {
+//     if (rdbuf()->connect(x1, ..., xn) == 0)
+//       this->setstate(std::ios_base::failbit);
+//   }
+// This macro should only persist within this file.
+
+# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  void connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
+  { \
+    if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
+      this->setstate(std::ios_base::failbit); \
+  } \
+  /**/
+
+#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// A separate base class is used to ensure that the streambuf is initialised
+// prior to the basic_socket_iostream's basic_iostream base class.
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+class socket_iostream_base
+{
+protected:
+  socket_iostream_base()
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  socket_iostream_base(socket_iostream_base&& other)
+    : streambuf_(std::move(other.streambuf_))
+  {
+  }
+
+  socket_iostream_base(basic_stream_socket<Protocol> s)
+    : streambuf_(std::move(s))
+  {
+  }
+
+  socket_iostream_base& operator=(socket_iostream_base&& other)
+  {
+    streambuf_ = std::move(other.streambuf_);
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+    Clock, WaitTraits BOOST_ASIO_SVC_TARG1> streambuf_;
+};
+
+} // namespace detail
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    typename Clock = boost::posix_time::ptime,
+    typename WaitTraits = time_traits<Clock>
+    BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    typename Clock = chrono::steady_clock,
+    typename WaitTraits = wait_traits<Clock>
+    BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+class basic_socket_iostream;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
+
+/// Iostream interface for a socket.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Protocol,
+    typename Clock = chrono::steady_clock,
+    typename WaitTraits = wait_traits<Clock> >
+#else // defined(GENERATING_DOCUMENTATION)
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+#endif // defined(GENERATING_DOCUMENTATION)
+class basic_socket_iostream
+  : private detail::socket_iostream_base<Protocol
+        BOOST_ASIO_SVC_TARG, Clock, WaitTraits BOOST_ASIO_SVC_TARG1>,
+    public std::basic_iostream<char>
+{
+private:
+  // These typedefs are intended keep this class's implementation independent
+  // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+  typedef WaitTraits traits_helper;
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+  typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+
+public:
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// The clock type.
+  typedef Clock clock_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// (Deprecated: Use time_point.) The time type.
+  typedef typename WaitTraits::time_type time_type;
+
+  /// The time type.
+  typedef typename WaitTraits::time_point time_point;
+
+  /// (Deprecated: Use duration.) The duration type.
+  typedef typename WaitTraits::duration_type duration_type;
+
+  /// The duration type.
+  typedef typename WaitTraits::duration duration;
+#else
+# if !defined(BOOST_ASIO_NO_DEPRECATED)
+  typedef typename traits_helper::time_type time_type;
+  typedef typename traits_helper::duration_type duration_type;
+# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+  typedef typename traits_helper::time_type time_point;
+  typedef typename traits_helper::duration_type duration;
+#endif
+
+  /// Construct a basic_socket_iostream without establishing a connection.
+  basic_socket_iostream()
+    : std::basic_iostream<char>(
+        &this->detail::socket_iostream_base<
+          Protocol BOOST_ASIO_SVC_TARG, Clock,
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+  {
+    this->setf(std::ios_base::unitbuf);
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Construct a basic_socket_iostream from the supplied socket.
+  explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
+    : detail::socket_iostream_base<
+        Protocol BOOST_ASIO_SVC_TARG, Clock,
+        WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(s)),
+      std::basic_iostream<char>(
+        &this->detail::socket_iostream_base<
+          Protocol BOOST_ASIO_SVC_TARG, Clock,
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+  {
+    this->setf(std::ios_base::unitbuf);
+  }
+
+#if defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE) \
+  || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_socket_iostream from another.
+  basic_socket_iostream(basic_socket_iostream&& other)
+    : detail::socket_iostream_base<
+        Protocol BOOST_ASIO_SVC_TARG, Clock,
+        WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(other)),
+      std::basic_iostream<char>(std::move(other))
+  {
+    this->set_rdbuf(&this->detail::socket_iostream_base<
+          Protocol BOOST_ASIO_SVC_TARG, Clock,
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+  }
+
+  /// Move-assign a basic_socket_iostream from another.
+  basic_socket_iostream& operator=(basic_socket_iostream&& other)
+  {
+    std::basic_iostream<char>::operator=(std::move(other));
+    detail::socket_iostream_base<
+        Protocol BOOST_ASIO_SVC_TARG, Clock,
+        WaitTraits BOOST_ASIO_SVC_TARG1>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
+       //   || defined(GENERATING_DOCUMENTATION)
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// Establish a connection to an endpoint corresponding to a resolver query.
+  /**
+   * This constructor automatically establishes a connection based on the
+   * supplied resolver query parameters. The arguments are used to construct
+   * a resolver query object.
+   */
+  template <typename T1, ..., typename TN>
+  explicit basic_socket_iostream(T1 t1, ..., TN tn);
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+  template <typename... T>
+  explicit basic_socket_iostream(T... x)
+    : std::basic_iostream<char>(
+        &this->detail::socket_iostream_base<
+          Protocol BOOST_ASIO_SVC_TARG, Clock,
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+  {
+    this->setf(std::ios_base::unitbuf);
+    if (rdbuf()->connect(x...) == 0)
+      this->setstate(std::ios_base::failbit);
+  }
+#else
+  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CTR_DEF)
+#endif
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// Establish a connection to an endpoint corresponding to a resolver query.
+  /**
+   * This function automatically establishes a connection based on the supplied
+   * resolver query parameters. The arguments are used to construct a resolver
+   * query object.
+   */
+  template <typename T1, ..., typename TN>
+  void connect(T1 t1, ..., TN tn);
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+  template <typename... T>
+  void connect(T... x)
+  {
+    if (rdbuf()->connect(x...) == 0)
+      this->setstate(std::ios_base::failbit);
+  }
+#else
+  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CONNECT_DEF)
+#endif
+
+  /// Close the connection.
+  void close()
+  {
+    if (rdbuf()->close() == 0)
+      this->setstate(std::ios_base::failbit);
+  }
+
+  /// Return a pointer to the underlying streambuf.
+  basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+    Clock, WaitTraits BOOST_ASIO_SVC_TARG1>* rdbuf() const
+  {
+    return const_cast<basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
+      Clock, WaitTraits BOOST_ASIO_SVC_TARG1>*>(
+        &this->detail::socket_iostream_base<
+          Protocol BOOST_ASIO_SVC_TARG, Clock,
+          WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+  }
+
+  /// Get a reference to the underlying socket.
+  basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+  {
+    return rdbuf()->socket();
+  }
+
+  /// Get the last error associated with the stream.
+  /**
+   * @return An \c error_code corresponding to the last error from the stream.
+   *
+   * @par Example
+   * To print the error associated with a failure to establish a connection:
+   * @code tcp::iostream s("www.boost.org", "http");
+   * if (!s)
+   * {
+   *   std::cout << "Error: " << s.error().message() << std::endl;
+   * } @endcode
+   */
+  const boost::system::error_code& error() const
+  {
+    return rdbuf()->error();
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the stream's expiry time as an absolute
+  /// time.
+  /**
+   * @return An absolute time value representing the stream's expiry time.
+   */
+  time_point expires_at() const
+  {
+    return rdbuf()->expires_at();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the stream's expiry time as an absolute time.
+  /**
+   * @return An absolute time value representing the stream's expiry time.
+   */
+  time_point expiry() const
+  {
+    return rdbuf()->expiry();
+  }
+
+  /// Set the stream's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the stream.
+   */
+  void expires_at(const time_point& expiry_time)
+  {
+    rdbuf()->expires_at(expiry_time);
+  }
+
+  /// Set the stream's expiry time relative to now.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   */
+  void expires_after(const duration& expiry_time)
+  {
+    rdbuf()->expires_after(expiry_time);
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the stream's expiry time relative to now.
+  /**
+   * @return A relative time value representing the stream's expiry time.
+   */
+  duration expires_from_now() const
+  {
+    return rdbuf()->expires_from_now();
+  }
+
+  /// (Deprecated: Use expires_after().) Set the stream's expiry time relative
+  /// to now.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   */
+  void expires_from_now(const duration& expiry_time)
+  {
+    rdbuf()->expires_from_now(expiry_time);
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+private:
+  // Disallow copying and assignment.
+  basic_socket_iostream(const basic_socket_iostream&) BOOST_ASIO_DELETED;
+  basic_socket_iostream& operator=(
+      const basic_socket_iostream&) BOOST_ASIO_DELETED;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+# undef BOOST_ASIO_PRIVATE_CTR_DEF
+# undef BOOST_ASIO_PRIVATE_CONNECT_DEF
+#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP

+ 709 - 0
cpir-read/boost/boost/asio/basic_socket_streambuf.hpp

@@ -0,0 +1,709 @@
+//
+// basic_socket_streambuf.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP
+#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#include <streambuf>
+#include <vector>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/basic_stream_socket.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/io_context.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+# if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#  include <boost/asio/deadline_timer_service.hpp>
+# else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#  include <boost/asio/detail/deadline_timer_service.hpp>
+# endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+# include <boost/asio/steady_timer.hpp>
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+
+#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+# include <boost/asio/detail/variadic_templates.hpp>
+
+// A macro that should expand to:
+//   template <typename T1, ..., typename Tn>
+//   basic_socket_streambuf* connect(T1 x1, ..., Tn xn)
+//   {
+//     init_buffers();
+//     typedef typename Protocol::resolver resolver_type;
+//     resolver_type resolver(socket().get_executor().context());
+//     connect_to_endpoints(
+//         resolver.resolve(x1, ..., xn, ec_));
+//     return !ec_ ? this : 0;
+//   }
+// This macro should only persist within this file.
+
+# define BOOST_ASIO_PRIVATE_CONNECT_DEF(n) \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  basic_socket_streambuf* connect(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
+  { \
+    init_buffers(); \
+    typedef typename Protocol::resolver resolver_type; \
+    resolver_type resolver(socket().get_executor().context()); \
+    connect_to_endpoints( \
+        resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
+    return !ec_ ? this : 0; \
+  } \
+  /**/
+
+#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# define BOOST_ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// A separate base class is used to ensure that the io_context member is
+// initialised prior to the basic_socket_streambuf's basic_socket base class.
+class socket_streambuf_io_context
+{
+protected:
+  socket_streambuf_io_context(io_context* ctx)
+    : default_io_context_(ctx)
+  {
+  }
+
+  shared_ptr<io_context> default_io_context_;
+};
+
+// A separate base class is used to ensure that the dynamically allocated
+// buffers are constructed prior to the basic_socket_streambuf's basic_socket
+// base class. This makes moving the socket is the last potentially throwing
+// step in the streambuf's move constructor, giving the constructor a strong
+// exception safety guarantee.
+class socket_streambuf_buffers
+{
+protected:
+  socket_streambuf_buffers()
+    : get_buffer_(buffer_size),
+      put_buffer_(buffer_size)
+  {
+  }
+
+  enum { buffer_size = 512 };
+  std::vector<char> get_buffer_;
+  std::vector<char> put_buffer_;
+};
+
+} // namespace detail
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    typename Clock = boost::posix_time::ptime,
+    typename WaitTraits = time_traits<Clock>
+    BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    typename Clock = chrono::steady_clock,
+    typename WaitTraits = wait_traits<Clock>
+    BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+class basic_socket_streambuf;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
+
+/// Iostream streambuf for a socket.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Protocol,
+    typename Clock = chrono::steady_clock,
+    typename WaitTraits = wait_traits<Clock> >
+#else // defined(GENERATING_DOCUMENTATION)
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+#endif // defined(GENERATING_DOCUMENTATION)
+class basic_socket_streambuf
+  : public std::streambuf,
+    private detail::socket_streambuf_io_context,
+    private detail::socket_streambuf_buffers,
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    private basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+    public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+{
+private:
+  // These typedefs are intended keep this class's implementation independent
+  // of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+  typedef WaitTraits traits_helper;
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+  typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+
+public:
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// The clock type.
+  typedef Clock clock_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// (Deprecated: Use time_point.) The time type.
+  typedef typename WaitTraits::time_type time_type;
+
+  /// The time type.
+  typedef typename WaitTraits::time_point time_point;
+
+  /// (Deprecated: Use duration.) The duration type.
+  typedef typename WaitTraits::duration_type duration_type;
+
+  /// The duration type.
+  typedef typename WaitTraits::duration duration;
+#else
+# if !defined(BOOST_ASIO_NO_DEPRECATED)
+  typedef typename traits_helper::time_type time_type;
+  typedef typename traits_helper::duration_type duration_type;
+# endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+  typedef typename traits_helper::time_type time_point;
+  typedef typename traits_helper::duration_type duration;
+#endif
+
+  /// Construct a basic_socket_streambuf without establishing a connection.
+  basic_socket_streambuf()
+    : detail::socket_streambuf_io_context(new io_context),
+      basic_socket<Protocol BOOST_ASIO_SVC_TARG>(*default_io_context_),
+      expiry_time_(max_expiry_time())
+  {
+    init_buffers();
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Construct a basic_socket_streambuf from the supplied socket.
+  explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
+    : detail::socket_streambuf_io_context(0),
+      basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(s)),
+      expiry_time_(max_expiry_time())
+  {
+    init_buffers();
+  }
+
+  /// Move-construct a basic_socket_streambuf from another.
+  basic_socket_streambuf(basic_socket_streambuf&& other)
+    : detail::socket_streambuf_io_context(other),
+      basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other.socket())),
+      ec_(other.ec_),
+      expiry_time_(other.expiry_time_)
+  {
+    get_buffer_.swap(other.get_buffer_);
+    put_buffer_.swap(other.put_buffer_);
+    setg(other.eback(), other.gptr(), other.egptr());
+    setp(other.pptr(), other.epptr());
+    other.ec_ = boost::system::error_code();
+    other.expiry_time_ = max_expiry_time();
+    other.init_buffers();
+  }
+
+  /// Move-assign a basic_socket_streambuf from another.
+  basic_socket_streambuf& operator=(basic_socket_streambuf&& other)
+  {
+    this->close();
+    socket() = std::move(other.socket());
+    detail::socket_streambuf_io_context::operator=(other);
+    ec_ = other.ec_;
+    expiry_time_ = other.expiry_time_;
+    get_buffer_.swap(other.get_buffer_);
+    put_buffer_.swap(other.put_buffer_);
+    setg(other.eback(), other.gptr(), other.egptr());
+    setp(other.pptr(), other.epptr());
+    other.ec_ = boost::system::error_code();
+    other.expiry_time_ = max_expiry_time();
+    other.put_buffer_.resize(buffer_size);
+    other.init_buffers();
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destructor flushes buffered data.
+  virtual ~basic_socket_streambuf()
+  {
+    if (pptr() != pbase())
+      overflow(traits_type::eof());
+  }
+
+  /// Establish a connection.
+  /**
+   * This function establishes a connection to the specified endpoint.
+   *
+   * @return \c this if a connection was successfully established, a null
+   * pointer otherwise.
+   */
+  basic_socket_streambuf* connect(const endpoint_type& endpoint)
+  {
+    init_buffers();
+    ec_ = boost::system::error_code();
+    this->connect_to_endpoints(&endpoint, &endpoint + 1);
+    return !ec_ ? this : 0;
+  }
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// Establish a connection.
+  /**
+   * This function automatically establishes a connection based on the supplied
+   * resolver query parameters. The arguments are used to construct a resolver
+   * query object.
+   *
+   * @return \c this if a connection was successfully established, a null
+   * pointer otherwise.
+   */
+  template <typename T1, ..., typename TN>
+  basic_socket_streambuf* connect(T1 t1, ..., TN tn);
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+  template <typename... T>
+  basic_socket_streambuf* connect(T... x)
+  {
+    init_buffers();
+    typedef typename Protocol::resolver resolver_type;
+    resolver_type resolver(socket().get_executor().context());
+    connect_to_endpoints(resolver.resolve(x..., ec_));
+    return !ec_ ? this : 0;
+  }
+#else
+  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_CONNECT_DEF)
+#endif
+
+  /// Close the connection.
+  /**
+   * @return \c this if a connection was successfully established, a null
+   * pointer otherwise.
+   */
+  basic_socket_streambuf* close()
+  {
+    sync();
+    socket().close(ec_);
+    if (!ec_)
+      init_buffers();
+    return !ec_ ? this : 0;
+  }
+
+  /// Get a reference to the underlying socket.
+  basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+  {
+    return *this;
+  }
+
+  /// Get the last error associated with the stream buffer.
+  /**
+   * @return An \c error_code corresponding to the last error from the stream
+   * buffer.
+   */
+  const boost::system::error_code& error() const
+  {
+    return ec_;
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use error().) Get the last error associated with the stream
+  /// buffer.
+  /**
+   * @return An \c error_code corresponding to the last error from the stream
+   * buffer.
+   */
+  const boost::system::error_code& puberror() const
+  {
+    return error();
+  }
+
+  /// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an
+  /// absolute time.
+  /**
+   * @return An absolute time value representing the stream buffer's expiry
+   * time.
+   */
+  time_point expires_at() const
+  {
+    return expiry_time_;
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the stream buffer's expiry time as an absolute time.
+  /**
+   * @return An absolute time value representing the stream buffer's expiry
+   * time.
+   */
+  time_point expiry() const
+  {
+    return expiry_time_;
+  }
+
+  /// Set the stream buffer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the stream.
+   */
+  void expires_at(const time_point& expiry_time)
+  {
+    expiry_time_ = expiry_time;
+  }
+
+  /// Set the stream buffer's expiry time relative to now.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   */
+  void expires_after(const duration& expiry_time)
+  {
+    expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative
+  /// to now.
+  /**
+   * @return A relative time value representing the stream buffer's expiry time.
+   */
+  duration expires_from_now() const
+  {
+    return traits_helper::subtract(expires_at(), traits_helper::now());
+  }
+
+  /// (Deprecated: Use expires_after().) Set the stream buffer's expiry time
+  /// relative to now.
+  /**
+   * This function sets the expiry time associated with the stream. Stream
+   * operations performed after this time (where the operations cannot be
+   * completed using the internal buffers) will fail with the error
+   * boost::asio::error::operation_aborted.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   */
+  void expires_from_now(const duration& expiry_time)
+  {
+    expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+protected:
+  int_type underflow()
+  {
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    ec_ = boost::asio::error::operation_not_supported;
+    return traits_type::eof();
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    if (gptr() != egptr())
+      return traits_type::eof();
+
+    for (;;)
+    {
+      // Check if we are past the expiry time.
+      if (traits_helper::less_than(expiry_time_, traits_helper::now()))
+      {
+        ec_ = boost::asio::error::timed_out;
+        return traits_type::eof();
+      }
+
+      // Try to complete the operation without blocking.
+      if (!socket().native_non_blocking())
+        socket().native_non_blocking(true, ec_);
+      detail::buffer_sequence_adapter<mutable_buffer, mutable_buffer>
+        bufs(boost::asio::buffer(get_buffer_) + putback_max);
+      detail::signed_size_type bytes = detail::socket_ops::recv(
+          socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
+
+      // Check if operation succeeded.
+      if (bytes > 0)
+      {
+        setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
+            &get_buffer_[0] + putback_max + bytes);
+        return traits_type::to_int_type(*gptr());
+      }
+
+      // Check for EOF.
+      if (bytes == 0)
+      {
+        ec_ = boost::asio::error::eof;
+        return traits_type::eof();
+      }
+
+      // Operation failed.
+      if (ec_ != boost::asio::error::would_block
+          && ec_ != boost::asio::error::try_again)
+        return traits_type::eof();
+
+      // Wait for socket to become ready.
+      if (detail::socket_ops::poll_read(
+            socket().native_handle(), 0, timeout(), ec_) < 0)
+        return traits_type::eof();
+    }
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  }
+
+  int_type overflow(int_type c)
+  {
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    ec_ = boost::asio::error::operation_not_supported;
+    return traits_type::eof();
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    char_type ch = traits_type::to_char_type(c);
+
+    // Determine what needs to be sent.
+    const_buffer output_buffer;
+    if (put_buffer_.empty())
+    {
+      if (traits_type::eq_int_type(c, traits_type::eof()))
+        return traits_type::not_eof(c); // Nothing to do.
+      output_buffer = boost::asio::buffer(&ch, sizeof(char_type));
+    }
+    else
+    {
+      output_buffer = boost::asio::buffer(pbase(),
+          (pptr() - pbase()) * sizeof(char_type));
+    }
+
+    while (output_buffer.size() > 0)
+    {
+      // Check if we are past the expiry time.
+      if (traits_helper::less_than(expiry_time_, traits_helper::now()))
+      {
+        ec_ = boost::asio::error::timed_out;
+        return traits_type::eof();
+      }
+
+      // Try to complete the operation without blocking.
+      if (!socket().native_non_blocking())
+        socket().native_non_blocking(true, ec_);
+      detail::buffer_sequence_adapter<
+        const_buffer, const_buffer> bufs(output_buffer);
+      detail::signed_size_type bytes = detail::socket_ops::send(
+          socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
+
+      // Check if operation succeeded.
+      if (bytes > 0)
+      {
+        output_buffer += static_cast<std::size_t>(bytes);
+        continue;
+      }
+
+      // Operation failed.
+      if (ec_ != boost::asio::error::would_block
+          && ec_ != boost::asio::error::try_again)
+        return traits_type::eof();
+
+      // Wait for socket to become ready.
+      if (detail::socket_ops::poll_write(
+            socket().native_handle(), 0, timeout(), ec_) < 0)
+        return traits_type::eof();
+    }
+
+    if (!put_buffer_.empty())
+    {
+      setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
+
+      // If the new character is eof then our work here is done.
+      if (traits_type::eq_int_type(c, traits_type::eof()))
+        return traits_type::not_eof(c);
+
+      // Add the new character to the output buffer.
+      *pptr() = ch;
+      pbump(1);
+    }
+
+    return c;
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  }
+
+  int sync()
+  {
+    return overflow(traits_type::eof());
+  }
+
+  std::streambuf* setbuf(char_type* s, std::streamsize n)
+  {
+    if (pptr() == pbase() && s == 0 && n == 0)
+    {
+      put_buffer_.clear();
+      setp(0, 0);
+      sync();
+      return this;
+    }
+
+    return 0;
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_socket_streambuf(const basic_socket_streambuf&) BOOST_ASIO_DELETED;
+  basic_socket_streambuf& operator=(
+      const basic_socket_streambuf&) BOOST_ASIO_DELETED;
+
+  void init_buffers()
+  {
+    setg(&get_buffer_[0],
+        &get_buffer_[0] + putback_max,
+        &get_buffer_[0] + putback_max);
+
+    if (put_buffer_.empty())
+      setp(0, 0);
+    else
+      setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
+  }
+
+  int timeout() const
+  {
+    int64_t msec = traits_helper::to_posix_duration(
+        traits_helper::subtract(expiry_time_,
+          traits_helper::now())).total_milliseconds();
+    if (msec > (std::numeric_limits<int>::max)())
+      msec = (std::numeric_limits<int>::max)();
+    else if (msec < 0)
+      msec = 0;
+    return static_cast<int>(msec);
+  }
+
+  template <typename EndpointSequence>
+  void connect_to_endpoints(const EndpointSequence& endpoints)
+  {
+    this->connect_to_endpoints(endpoints.begin(), endpoints.end());
+  }
+
+  template <typename EndpointIterator>
+  void connect_to_endpoints(EndpointIterator begin, EndpointIterator end)
+  {
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    ec_ = boost::asio::error::operation_not_supported;
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    if (ec_)
+      return;
+
+    ec_ = boost::asio::error::not_found;
+    for (EndpointIterator i = begin; i != end; ++i)
+    {
+      // Check if we are past the expiry time.
+      if (traits_helper::less_than(expiry_time_, traits_helper::now()))
+      {
+        ec_ = boost::asio::error::timed_out;
+        return;
+      }
+
+      // Close and reopen the socket.
+      typename Protocol::endpoint ep(*i);
+      socket().close(ec_);
+      socket().open(ep.protocol(), ec_);
+      if (ec_)
+        continue;
+
+      // Try to complete the operation without blocking.
+      if (!socket().native_non_blocking())
+        socket().native_non_blocking(true, ec_);
+      detail::socket_ops::connect(socket().native_handle(),
+          ep.data(), ep.size(), ec_);
+
+      // Check if operation succeeded.
+      if (!ec_)
+        return;
+
+      // Operation failed.
+      if (ec_ != boost::asio::error::in_progress
+          && ec_ != boost::asio::error::would_block)
+        continue;
+
+      // Wait for socket to become ready.
+      if (detail::socket_ops::poll_connect(
+            socket().native_handle(), timeout(), ec_) < 0)
+        continue;
+
+      // Get the error code from the connect operation.
+      int connect_error = 0;
+      size_t connect_error_len = sizeof(connect_error);
+      if (detail::socket_ops::getsockopt(socket().native_handle(), 0,
+            SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_)
+          == detail::socket_error_retval)
+        return;
+
+      // Check the result of the connect operation.
+      ec_ = boost::system::error_code(connect_error,
+          boost::asio::error::get_system_category());
+      if (!ec_)
+        return;
+    }
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  }
+
+  // Helper function to get the maximum expiry time.
+  static time_point max_expiry_time()
+  {
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    return boost::posix_time::pos_infin;
+#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+      // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+    return (time_point::max)();
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
+  }
+
+  enum { putback_max = 8 };
+  boost::system::error_code ec_;
+  time_point expiry_time_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T1
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+# undef BOOST_ASIO_PRIVATE_CONNECT_DEF
+#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP

+ 923 - 0
cpir-read/boost/boost/asio/basic_stream_socket.hpp

@@ -0,0 +1,923 @@
+//
+// basic_stream_socket.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
+#define BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/stream_socket_service.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Provides stream-oriented socket functionality.
+/**
+ * The basic_stream_socket class template provides asynchronous and blocking
+ * stream-oriented socket functionality.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
+ */
+template <typename Protocol
+    BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
+class basic_stream_socket
+  : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+{
+public:
+  /// The native representation of a socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename basic_socket<
+    Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+  /// Construct a basic_stream_socket without opening it.
+  /**
+   * This constructor creates a stream socket without opening it. The socket
+   * needs to be opened and then connected or accepted before data can be sent
+   * or received on it.
+   *
+   * @param io_context The io_context object that the stream socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   */
+  explicit basic_stream_socket(boost::asio::io_context& io_context)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+  {
+  }
+
+  /// Construct and open a basic_stream_socket.
+  /**
+   * This constructor creates and opens a stream socket. The socket needs to be
+   * connected or accepted before data can be sent or received on it.
+   *
+   * @param io_context The io_context object that the stream socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_stream_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+  {
+  }
+
+  /// Construct a basic_stream_socket, opening it and binding it to the given
+  /// local endpoint.
+  /**
+   * This constructor creates a stream socket and automatically opens it bound
+   * to the specified endpoint on the local machine. The protocol used is the
+   * protocol associated with the given endpoint.
+   *
+   * @param io_context The io_context object that the stream socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param endpoint An endpoint on the local machine to which the stream
+   * socket will be bound.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_stream_socket(boost::asio::io_context& io_context,
+      const endpoint_type& endpoint)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+  {
+  }
+
+  /// Construct a basic_stream_socket on an existing native socket.
+  /**
+   * This constructor creates a stream socket object to hold an existing native
+   * socket.
+   *
+   * @param io_context The io_context object that the stream socket will use to
+   * dispatch handlers for any asynchronous operations performed on the socket.
+   *
+   * @param protocol An object specifying protocol parameters to be used.
+   *
+   * @param native_socket The new underlying socket implementation.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  basic_stream_socket(boost::asio::io_context& io_context,
+      const protocol_type& protocol, const native_handle_type& native_socket)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
+        io_context, protocol, native_socket)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_stream_socket from another.
+  /**
+   * This constructor moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_context&) constructor.
+   */
+  basic_stream_socket(basic_stream_socket&& other)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_stream_socket from another.
+  /**
+   * This assignment operator moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_context&) constructor.
+   */
+  basic_stream_socket& operator=(basic_stream_socket&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+
+  /// Move-construct a basic_stream_socket from a socket of another protocol
+  /// type.
+  /**
+   * This constructor moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  basic_stream_socket(
+      basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
+      typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
+    : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_stream_socket from a socket of another protocol type.
+  /**
+   * This assignment operator moves a stream socket from one object to another.
+   *
+   * @param other The other basic_stream_socket object from which the move
+   * will occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_stream_socket(io_context&) constructor.
+   */
+  template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+  typename enable_if<is_convertible<Protocol1, Protocol>::value,
+      basic_stream_socket>::type& operator=(
+        basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+  {
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the socket.
+  /**
+   * This function destroys the socket, cancelling any outstanding asynchronous
+   * operations associated with the socket as if by calling @c cancel.
+   */
+  ~basic_stream_socket()
+  {
+  }
+
+  /// Send some data on the socket.
+  /**
+   * This function is used to send data on the stream socket. The function
+   * call will block until one or more bytes of the data has been sent
+   * successfully, or an until error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref write function if you need to ensure that all data
+   * is written before the blocking operation completes.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.send(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on the socket.
+  /**
+   * This function is used to send data on the stream socket. The function
+   * call will block until one or more bytes of the data has been sent
+   * successfully, or an until error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @returns The number of bytes sent.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref write function if you need to ensure that all data
+   * is written before the blocking operation completes.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.send(boost::asio::buffer(data, size), 0);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "send");
+    return s;
+  }
+
+  /// Send some data on the socket.
+  /**
+   * This function is used to send data on the stream socket. The function
+   * call will block until one or more bytes of the data has been sent
+   * successfully, or an until error occurs.
+   *
+   * @param buffers One or more data buffers to be sent on the socket.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes sent. Returns 0 if an error occurred.
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref write function if you need to ensure that all data
+   * is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().send(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send data on the stream socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write function if you need to ensure that all
+   * data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(
+        this->get_implementation(), buffers, 0,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(
+        this->get_implementation(), buffers, 0,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous send.
+  /**
+   * This function is used to asynchronously send data on the stream socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be sent on the socket. Although
+   * the buffers object may be copied as necessary, ownership of the underlying
+   * memory blocks is retained by the caller, which must guarantee that they
+   * remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the send call is to be made.
+   *
+   * @param handler The handler to be called when the send operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes sent.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The send operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write function if you need to ensure that all
+   * data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To send a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_send(boost::asio::buffer(data, size), 0, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on sending multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(
+        this->get_implementation(), buffers, flags,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(
+        this->get_implementation(), buffers, flags,
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Receive some data on the socket.
+  /**
+   * This function is used to receive data on the stream socket. The function
+   * call will block until one or more bytes of data has been received
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that the
+   * requested amount of data is read before the blocking operation completes.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.receive(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on the socket.
+  /**
+   * This function is used to receive data on the stream socket. The function
+   * call will block until one or more bytes of data has been received
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @returns The number of bytes received.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that the
+   * requested amount of data is read before the blocking operation completes.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.receive(boost::asio::buffer(data, size), 0);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+    boost::asio::detail::throw_error(ec, "receive");
+    return s;
+  }
+
+  /// Receive some data on a connected socket.
+  /**
+   * This function is used to receive data on the stream socket. The function
+   * call will block until one or more bytes of data has been received
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes received. Returns 0 if an error occurred.
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that the
+   * requested amount of data is read before the blocking operation completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return this->get_service().receive(
+        this->get_implementation(), buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive data from the stream
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref async_read function if you need to ensure
+   * that the requested amount of data is received before the asynchronous
+   * operation completes.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Start an asynchronous receive.
+  /**
+   * This function is used to asynchronously receive data from the stream
+   * socket. The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be received.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param flags Flags specifying how the receive call is to be made.
+   *
+   * @param handler The handler to be called when the receive operation
+   * completes. Copies will be made of the handler as required. The function
+   * signature of the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes received.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The receive operation may not receive all of the requested number of
+   * bytes. Consider using the @ref async_read function if you need to ensure
+   * that the requested amount of data is received before the asynchronous
+   * operation completes.
+   *
+   * @par Example
+   * To receive into a single data buffer use the @ref buffer function as
+   * follows:
+   * @code
+   * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
+   * @endcode
+   * See the @ref buffer documentation for information on receiving into
+   * multiple buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, flags, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Write some data to the socket.
+  /**
+   * This function is used to write data to the stream socket. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the socket.
+   *
+   * @returns The number of bytes written.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.write_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().send(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "write_some");
+    return s;
+  }
+
+  /// Write some data to the socket.
+  /**
+   * This function is used to write data to the stream socket. The function call
+   * will block until one or more bytes of the data has been written
+   * successfully, or until an error occurs.
+   *
+   * @param buffers One or more data buffers to be written to the socket.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes written. Returns 0 if an error occurred.
+   *
+   * @note The write_some operation may not transmit all of the data to the
+   * peer. Consider using the @ref write function if you need to ensure that
+   * all data is written before the blocking operation completes.
+   */
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().send(this->get_implementation(), buffers, 0, ec);
+  }
+
+  /// Start an asynchronous write.
+  /**
+   * This function is used to asynchronously write data to the stream socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more data buffers to be written to the socket.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the write operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes written.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The write operation may not transmit all of the data to the peer.
+   * Consider using the @ref async_write function if you need to ensure that all
+   * data is written before the asynchronous operation completes.
+   *
+   * @par Example
+   * To write a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_write_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on writing multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_write_some(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WriteHandler.
+    BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_send(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_send(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+  /// Read some data from the socket.
+  /**
+   * This function is used to read data from the stream socket. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @returns The number of bytes read.
+   *
+   * @throws boost::system::system_error Thrown on failure. An error code of
+   * boost::asio::error::eof indicates that the connection was closed by the
+   * peer.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.read_some(boost::asio::buffer(data, size));
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().receive(
+        this->get_implementation(), buffers, 0, ec);
+    boost::asio::detail::throw_error(ec, "read_some");
+    return s;
+  }
+
+  /// Read some data from the socket.
+  /**
+   * This function is used to read data from the stream socket. The function
+   * call will block until one or more bytes of data has been read successfully,
+   * or until an error occurs.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @returns The number of bytes read. Returns 0 if an error occurred.
+   *
+   * @note The read_some operation may not read all of the requested number of
+   * bytes. Consider using the @ref read function if you need to ensure that
+   * the requested amount of data is read before the blocking operation
+   * completes.
+   */
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().receive(
+        this->get_implementation(), buffers, 0, ec);
+  }
+
+  /// Start an asynchronous read.
+  /**
+   * This function is used to asynchronously read data from the stream socket.
+   * The function call always returns immediately.
+   *
+   * @param buffers One or more buffers into which the data will be read.
+   * Although the buffers object may be copied as necessary, ownership of the
+   * underlying memory blocks is retained by the caller, which must guarantee
+   * that they remain valid until the handler is called.
+   *
+   * @param handler The handler to be called when the read operation completes.
+   * Copies will be made of the handler as required. The function signature of
+   * the handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error, // Result of operation.
+   *   std::size_t bytes_transferred           // Number of bytes read.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   *
+   * @note The read operation may not read all of the requested number of bytes.
+   * Consider using the @ref async_read function if you need to ensure that the
+   * requested amount of data is read before the asynchronous operation
+   * completes.
+   *
+   * @par Example
+   * To read into a single data buffer use the @ref buffer function as follows:
+   * @code
+   * socket.async_read_some(boost::asio::buffer(data, size), handler);
+   * @endcode
+   * See the @ref buffer documentation for information on reading into multiple
+   * buffers in one go, and how to use it with arrays, boost::array or
+   * std::vector.
+   */
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_read_some(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a ReadHandler.
+    BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    this->get_service().async_receive(this->get_implementation(),
+        buffers, 0, init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP

+ 454 - 0
cpir-read/boost/boost/asio/basic_streambuf.hpp

@@ -0,0 +1,454 @@
+//
+// basic_streambuf.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_STREAMBUF_HPP
+#define BOOST_ASIO_BASIC_STREAMBUF_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#include <algorithm>
+#include <cstring>
+#include <stdexcept>
+#include <streambuf>
+#include <vector>
+#include <boost/asio/basic_streambuf_fwd.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/limits.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/throw_exception.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Automatically resizable buffer class based on std::streambuf.
+/**
+ * The @c basic_streambuf class is derived from @c std::streambuf to associate
+ * the streambuf's input and output sequences with one or more character
+ * arrays. These character arrays are internal to the @c basic_streambuf
+ * object, but direct access to the array elements is provided to permit them
+ * to be used efficiently with I/O operations. Characters written to the output
+ * sequence of a @c basic_streambuf object are appended to the input sequence
+ * of the same object.
+ *
+ * The @c basic_streambuf class's public interface is intended to permit the
+ * following implementation strategies:
+ *
+ * @li A single contiguous character array, which is reallocated as necessary
+ * to accommodate changes in the size of the character sequence. This is the
+ * implementation approach currently used in Asio.
+ *
+ * @li A sequence of one or more character arrays, where each array is of the
+ * same size. Additional character array objects are appended to the sequence
+ * to accommodate changes in the size of the character sequence.
+ *
+ * @li A sequence of one or more character arrays of varying sizes. Additional
+ * character array objects are appended to the sequence to accommodate changes
+ * in the size of the character sequence.
+ *
+ * The constructor for basic_streambuf accepts a @c size_t argument specifying
+ * the maximum of the sum of the sizes of the input sequence and output
+ * sequence. During the lifetime of the @c basic_streambuf object, the following
+ * invariant holds:
+ * @code size() <= max_size()@endcode
+ * Any member function that would, if successful, cause the invariant to be
+ * violated shall throw an exception of class @c std::length_error.
+ *
+ * The constructor for @c basic_streambuf takes an Allocator argument. A copy
+ * of this argument is used for any memory allocation performed, by the
+ * constructor and by all member functions, during the lifetime of each @c
+ * basic_streambuf object.
+ *
+ * @par Examples
+ * Writing directly from an streambuf to a socket:
+ * @code
+ * boost::asio::streambuf b;
+ * std::ostream os(&b);
+ * os << "Hello, World!\n";
+ *
+ * // try sending some data in input sequence
+ * size_t n = sock.send(b.data());
+ *
+ * b.consume(n); // sent data is removed from input sequence
+ * @endcode
+ *
+ * Reading from a socket directly into a streambuf:
+ * @code
+ * boost::asio::streambuf b;
+ *
+ * // reserve 512 bytes in output sequence
+ * boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
+ *
+ * size_t n = sock.receive(bufs);
+ *
+ * // received data is "committed" from output sequence to input sequence
+ * b.commit(n);
+ *
+ * std::istream is(&b);
+ * std::string s;
+ * is >> s;
+ * @endcode
+ */
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Allocator = std::allocator<char> >
+#else
+template <typename Allocator>
+#endif
+class basic_streambuf
+  : public std::streambuf,
+    private noncopyable
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// The type used to represent the input sequence as a list of buffers.
+  typedef implementation_defined const_buffers_type;
+
+  /// The type used to represent the output sequence as a list of buffers.
+  typedef implementation_defined mutable_buffers_type;
+#else
+  typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+  typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
+#endif
+
+  /// Construct a basic_streambuf object.
+  /**
+   * Constructs a streambuf with the specified maximum size. The initial size
+   * of the streambuf's input sequence is 0.
+   */
+  explicit basic_streambuf(
+      std::size_t maximum_size = (std::numeric_limits<std::size_t>::max)(),
+      const Allocator& allocator = Allocator())
+    : max_size_(maximum_size),
+      buffer_(allocator)
+  {
+    std::size_t pend = (std::min<std::size_t>)(max_size_, buffer_delta);
+    buffer_.resize((std::max<std::size_t>)(pend, 1));
+    setg(&buffer_[0], &buffer_[0], &buffer_[0]);
+    setp(&buffer_[0], &buffer_[0] + pend);
+  }
+
+  /// Get the size of the input sequence.
+  /**
+   * @returns The size of the input sequence. The value is equal to that
+   * calculated for @c s in the following code:
+   * @code
+   * size_t s = 0;
+   * const_buffers_type bufs = data();
+   * const_buffers_type::const_iterator i = bufs.begin();
+   * while (i != bufs.end())
+   * {
+   *   const_buffer buf(*i++);
+   *   s += buf.size();
+   * }
+   * @endcode
+   */
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return pptr() - gptr();
+  }
+
+  /// Get the maximum size of the basic_streambuf.
+  /**
+   * @returns The allowed maximum of the sum of the sizes of the input sequence
+   * and output sequence.
+   */
+  std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+  {
+    return max_size_;
+  }
+
+  /// Get the current capacity of the basic_streambuf.
+  /**
+   * @returns The current total capacity of the streambuf, i.e. for both the
+   * input sequence and output sequence.
+   */
+  std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+  {
+    return buffer_.capacity();
+  }
+
+  /// Get a list of buffers that represents the input sequence.
+  /**
+   * @returns An object of type @c const_buffers_type that satisfies
+   * ConstBufferSequence requirements, representing all character arrays in the
+   * input sequence.
+   *
+   * @note The returned object is invalidated by any @c basic_streambuf member
+   * function that modifies the input sequence or output sequence.
+   */
+  const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+  {
+    return boost::asio::buffer(boost::asio::const_buffer(gptr(),
+          (pptr() - gptr()) * sizeof(char_type)));
+  }
+
+  /// Get a list of buffers that represents the output sequence, with the given
+  /// size.
+  /**
+   * Ensures that the output sequence can accommodate @c n characters,
+   * reallocating character array objects as necessary.
+   *
+   * @returns An object of type @c mutable_buffers_type that satisfies
+   * MutableBufferSequence requirements, representing character array objects
+   * at the start of the output sequence such that the sum of the buffer sizes
+   * is @c n.
+   *
+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+   *
+   * @note The returned object is invalidated by any @c basic_streambuf member
+   * function that modifies the input sequence or output sequence.
+   */
+  mutable_buffers_type prepare(std::size_t n)
+  {
+    reserve(n);
+    return boost::asio::buffer(boost::asio::mutable_buffer(
+          pptr(), n * sizeof(char_type)));
+  }
+
+  /// Move characters from the output sequence to the input sequence.
+  /**
+   * Appends @c n characters from the start of the output sequence to the input
+   * sequence. The beginning of the output sequence is advanced by @c n
+   * characters.
+   *
+   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
+   * no intervening operations that modify the input or output sequence.
+   *
+   * @note If @c n is greater than the size of the output sequence, the entire
+   * output sequence is moved to the input sequence and no error is issued.
+   */
+  void commit(std::size_t n)
+  {
+    n = std::min<std::size_t>(n, epptr() - pptr());
+    pbump(static_cast<int>(n));
+    setg(eback(), gptr(), pptr());
+  }
+
+  /// Remove characters from the input sequence.
+  /**
+   * Removes @c n characters from the beginning of the input sequence.
+   *
+   * @note If @c n is greater than the size of the input sequence, the entire
+   * input sequence is consumed and no error is issued.
+   */
+  void consume(std::size_t n)
+  {
+    if (egptr() < pptr())
+      setg(&buffer_[0], gptr(), pptr());
+    if (gptr() + n > pptr())
+      n = pptr() - gptr();
+    gbump(static_cast<int>(n));
+  }
+
+protected:
+  enum { buffer_delta = 128 };
+
+  /// Override std::streambuf behaviour.
+  /**
+   * Behaves according to the specification of @c std::streambuf::underflow().
+   */
+  int_type underflow()
+  {
+    if (gptr() < pptr())
+    {
+      setg(&buffer_[0], gptr(), pptr());
+      return traits_type::to_int_type(*gptr());
+    }
+    else
+    {
+      return traits_type::eof();
+    }
+  }
+
+  /// Override std::streambuf behaviour.
+  /**
+   * Behaves according to the specification of @c std::streambuf::overflow(),
+   * with the specialisation that @c std::length_error is thrown if appending
+   * the character to the input sequence would require the condition
+   * <tt>size() > max_size()</tt> to be true.
+   */
+  int_type overflow(int_type c)
+  {
+    if (!traits_type::eq_int_type(c, traits_type::eof()))
+    {
+      if (pptr() == epptr())
+      {
+        std::size_t buffer_size = pptr() - gptr();
+        if (buffer_size < max_size_ && max_size_ - buffer_size < buffer_delta)
+        {
+          reserve(max_size_ - buffer_size);
+        }
+        else
+        {
+          reserve(buffer_delta);
+        }
+      }
+
+      *pptr() = traits_type::to_char_type(c);
+      pbump(1);
+      return c;
+    }
+
+    return traits_type::not_eof(c);
+  }
+
+  void reserve(std::size_t n)
+  {
+    // Get current stream positions as offsets.
+    std::size_t gnext = gptr() - &buffer_[0];
+    std::size_t pnext = pptr() - &buffer_[0];
+    std::size_t pend = epptr() - &buffer_[0];
+
+    // Check if there is already enough space in the put area.
+    if (n <= pend - pnext)
+    {
+      return;
+    }
+
+    // Shift existing contents of get area to start of buffer.
+    if (gnext > 0)
+    {
+      pnext -= gnext;
+      std::memmove(&buffer_[0], &buffer_[0] + gnext, pnext);
+    }
+
+    // Ensure buffer is large enough to hold at least the specified size.
+    if (n > pend - pnext)
+    {
+      if (n <= max_size_ && pnext <= max_size_ - n)
+      {
+        pend = pnext + n;
+        buffer_.resize((std::max<std::size_t>)(pend, 1));
+      }
+      else
+      {
+        std::length_error ex("boost::asio::streambuf too long");
+        boost::asio::detail::throw_exception(ex);
+      }
+    }
+
+    // Update stream positions.
+    setg(&buffer_[0], &buffer_[0], &buffer_[0] + pnext);
+    setp(&buffer_[0] + pnext, &buffer_[0] + pend);
+  }
+
+private:
+  std::size_t max_size_;
+  std::vector<char_type, Allocator> buffer_;
+
+  // Helper function to get the preferred size for reading data.
+  friend std::size_t read_size_helper(
+      basic_streambuf& sb, std::size_t max_size)
+  {
+    return std::min<std::size_t>(
+        std::max<std::size_t>(512, sb.buffer_.capacity() - sb.size()),
+        std::min<std::size_t>(max_size, sb.max_size() - sb.size()));
+  }
+};
+
+/// Adapts basic_streambuf to the dynamic buffer sequence type requirements.
+#if defined(GENERATING_DOCUMENTATION)
+template <typename Allocator = std::allocator<char> >
+#else
+template <typename Allocator>
+#endif
+class basic_streambuf_ref
+{
+public:
+  /// The type used to represent the input sequence as a list of buffers.
+  typedef typename basic_streambuf<Allocator>::const_buffers_type
+    const_buffers_type;
+
+  /// The type used to represent the output sequence as a list of buffers.
+  typedef typename basic_streambuf<Allocator>::mutable_buffers_type
+    mutable_buffers_type;
+
+  /// Construct a basic_streambuf_ref for the given basic_streambuf object.
+  explicit basic_streambuf_ref(basic_streambuf<Allocator>& sb)
+    : sb_(sb)
+  {
+  }
+
+  /// Copy construct a basic_streambuf_ref.
+  basic_streambuf_ref(const basic_streambuf_ref& other) BOOST_ASIO_NOEXCEPT
+    : sb_(other.sb_)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move construct a basic_streambuf_ref.
+  basic_streambuf_ref(basic_streambuf_ref&& other) BOOST_ASIO_NOEXCEPT
+    : sb_(other.sb_)
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Get the size of the input sequence.
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return sb_.size();
+  }
+
+  /// Get the maximum size of the dynamic buffer.
+  std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+  {
+    return sb_.max_size();
+  }
+
+  /// Get the current capacity of the dynamic buffer.
+  std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+  {
+    return sb_.capacity();
+  }
+
+  /// Get a list of buffers that represents the input sequence.
+  const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+  {
+    return sb_.data();
+  }
+
+  /// Get a list of buffers that represents the output sequence, with the given
+  /// size.
+  mutable_buffers_type prepare(std::size_t n)
+  {
+    return sb_.prepare(n);
+  }
+
+  /// Move bytes from the output sequence to the input sequence.
+  void commit(std::size_t n)
+  {
+    return sb_.commit(n);
+  }
+
+  /// Remove characters from the input sequence.
+  void consume(std::size_t n)
+  {
+    return sb_.consume(n);
+  }
+
+private:
+  basic_streambuf<Allocator>& sb_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_BASIC_STREAMBUF_HPP

+ 38 - 0
cpir-read/boost/boost/asio/basic_streambuf_fwd.hpp

@@ -0,0 +1,38 @@
+//
+// basic_streambuf_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP
+#define BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#include <memory>
+
+namespace boost {
+namespace asio {
+
+template <typename Allocator = std::allocator<char> >
+class basic_streambuf;
+
+template <typename Allocator = std::allocator<char> >
+class basic_streambuf_ref;
+
+} // namespace asio
+} // namespace boost
+
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP

+ 707 - 0
cpir-read/boost/boost/asio/basic_waitable_timer.hpp

@@ -0,0 +1,707 @@
+//
+// basic_waitable_timer.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
+#define BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/wait_traits.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/waitable_timer_service.hpp>
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/chrono_time_traits.hpp>
+# include <boost/asio/detail/deadline_timer_service.hpp>
+# define BOOST_ASIO_SVC_T \
+    detail::deadline_timer_service< \
+      detail::chrono_time_traits<Clock, WaitTraits> >
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
+#define BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Clock,
+    typename WaitTraits = boost::asio::wait_traits<Clock>
+    BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
+class basic_waitable_timer;
+
+#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
+
+/// Provides waitable timer functionality.
+/**
+ * The basic_waitable_timer class template provides the ability to perform a
+ * blocking or asynchronous wait for a timer to expire.
+ *
+ * A waitable timer is always in one of two states: "expired" or "not expired".
+ * If the wait() or async_wait() function is called on an expired timer, the
+ * wait operation will complete immediately.
+ *
+ * Most applications will use one of the boost::asio::steady_timer,
+ * boost::asio::system_timer or boost::asio::high_resolution_timer typedefs.
+ *
+ * @note This waitable timer functionality is for use with the C++11 standard
+ * library's @c &lt;chrono&gt; facility, or with the Boost.Chrono library.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Examples
+ * Performing a blocking wait (C++11):
+ * @code
+ * // Construct a timer without setting an expiry time.
+ * boost::asio::steady_timer timer(io_context);
+ *
+ * // Set an expiry time relative to now.
+ * timer.expires_after(std::chrono::seconds(5));
+ *
+ * // Wait for the timer to expire.
+ * timer.wait();
+ * @endcode
+ *
+ * @par 
+ * Performing an asynchronous wait (C++11):
+ * @code
+ * void handler(const boost::system::error_code& error)
+ * {
+ *   if (!error)
+ *   {
+ *     // Timer expired.
+ *   }
+ * }
+ *
+ * ...
+ *
+ * // Construct a timer with an absolute expiry time.
+ * boost::asio::steady_timer timer(io_context,
+ *     std::chrono::steady_clock::now() + std::chrono::seconds(60));
+ *
+ * // Start an asynchronous wait.
+ * timer.async_wait(handler);
+ * @endcode
+ *
+ * @par Changing an active waitable timer's expiry time
+ *
+ * Changing the expiry time of a timer while there are pending asynchronous
+ * waits causes those wait operations to be cancelled. To ensure that the action
+ * associated with the timer is performed only once, use something like this:
+ * used:
+ *
+ * @code
+ * void on_some_event()
+ * {
+ *   if (my_timer.expires_after(seconds(5)) > 0)
+ *   {
+ *     // We managed to cancel the timer. Start new asynchronous wait.
+ *     my_timer.async_wait(on_timeout);
+ *   }
+ *   else
+ *   {
+ *     // Too late, timer has already expired!
+ *   }
+ * }
+ *
+ * void on_timeout(const boost::system::error_code& e)
+ * {
+ *   if (e != boost::asio::error::operation_aborted)
+ *   {
+ *     // Timer was not cancelled, take necessary action.
+ *   }
+ * }
+ * @endcode
+ *
+ * @li The boost::asio::basic_waitable_timer::expires_after() function
+ * cancels any pending asynchronous waits, and returns the number of
+ * asynchronous waits that were cancelled. If it returns 0 then you were too
+ * late and the wait handler has already been executed, or will soon be
+ * executed. If it returns 1 then the wait handler was successfully cancelled.
+ *
+ * @li If a wait handler is cancelled, the boost::system::error_code passed to
+ * it contains the value boost::asio::error::operation_aborted.
+ */
+template <typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM>
+class basic_waitable_timer
+  : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
+{
+public:
+  /// The type of the executor associated with the object.
+  typedef io_context::executor_type executor_type;
+
+  /// The clock type.
+  typedef Clock clock_type;
+
+  /// The duration type of the clock.
+  typedef typename clock_type::duration duration;
+
+  /// The time point type of the clock.
+  typedef typename clock_type::time_point time_point;
+
+  /// The wait traits type.
+  typedef WaitTraits traits_type;
+
+  /// Constructor.
+  /**
+   * This constructor creates a timer without setting an expiry time. The
+   * expires_at() or expires_after() functions must be called to set an expiry
+   * time before the timer can be waited on.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   */
+  explicit basic_waitable_timer(boost::asio::io_context& io_context)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+  }
+
+  /// Constructor to set a particular expiry time as an absolute time.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, expressed
+   * as an absolute time.
+   */
+  basic_waitable_timer(boost::asio::io_context& io_context,
+      const time_point& expiry_time)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_at");
+  }
+
+  /// Constructor to set a particular expiry time relative to now.
+  /**
+   * This constructor creates a timer and sets the expiry time.
+   *
+   * @param io_context The io_context object that the timer will use to dispatch
+   * handlers for any asynchronous operations performed on the timer.
+   *
+   * @param expiry_time The expiry time to be used for the timer, relative to
+   * now.
+   */
+  basic_waitable_timer(boost::asio::io_context& io_context,
+      const duration& expiry_time)
+    : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+  {
+    boost::system::error_code ec;
+    this->get_service().expires_after(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_after");
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a basic_waitable_timer from another.
+  /**
+   * This constructor moves a timer from one object to another.
+   *
+   * @param other The other basic_waitable_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_waitable_timer(io_context&) constructor.
+   */
+  basic_waitable_timer(basic_waitable_timer&& other)
+    : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+  {
+  }
+
+  /// Move-assign a basic_waitable_timer from another.
+  /**
+   * This assignment operator moves a timer from one object to another. Cancels
+   * any outstanding asynchronous operations associated with the target object.
+   *
+   * @param other The other basic_waitable_timer object from which the move will
+   * occur.
+   *
+   * @note Following the move, the moved-from object is in the same state as if
+   * constructed using the @c basic_waitable_timer(io_context&) constructor.
+   */
+  basic_waitable_timer& operator=(basic_waitable_timer&& other)
+  {
+    basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+    return *this;
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroys the timer.
+  /**
+   * This function destroys the timer, cancelling any outstanding asynchronous
+   * wait operations associated with the timer as if by calling @c cancel.
+   */
+  ~basic_waitable_timer()
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  // These functions are provided by basic_io_object<>.
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_context()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  /**
+   * This function may be used to obtain the io_context object that the I/O
+   * object uses to dispatch handlers for asynchronous operations.
+   *
+   * @return A reference to the io_context object that the I/O object will use
+   * to dispatch handlers. Ownership is not transferred to the caller.
+   */
+  boost::asio::io_context& get_io_service()
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+  }
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+  /// Cancel any asynchronous operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel()
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel");
+    return s;
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous
+  /// operations that are waiting on the timer.
+  /**
+   * This function forces the completion of any pending asynchronous wait
+   * operations against the timer. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when cancel() is called, then the
+   * handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel(boost::system::error_code& ec)
+  {
+    return this->get_service().cancel(this->get_implementation(), ec);
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Cancels one asynchronous operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one()
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().cancel_one(
+        this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "cancel_one");
+    return s;
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous
+  /// operation that is waiting on the timer.
+  /**
+   * This function forces the completion of one pending asynchronous wait
+   * operation against the timer. Handlers are cancelled in FIFO order. The
+   * handler for the cancelled operation will be invoked with the
+   * boost::asio::error::operation_aborted error code.
+   *
+   * Cancelling the timer does not change the expiry time.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled. That is,
+   * either 0 or 1.
+   *
+   * @note If the timer has already expired when cancel_one() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t cancel_one(boost::system::error_code& ec)
+  {
+    return this->get_service().cancel_one(this->get_implementation(), ec);
+  }
+
+  /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
+  /// time.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  time_point expires_at() const
+  {
+    return this->get_service().expires_at(this->get_implementation());
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Get the timer's expiry time as an absolute time.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  time_point expiry() const
+  {
+    return this->get_service().expiry(this->get_implementation());
+  }
+
+  /// Set the timer's expiry time as an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_point& expiry_time)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_at");
+    return s;
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as
+  /// an absolute time.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_at() is called, then
+   * the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_at(const time_point& expiry_time,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().expires_at(
+        this->get_implementation(), expiry_time, ec);
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Set the timer's expiry time relative to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_after() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_after(const duration& expiry_time)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().expires_after(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_after");
+    return s;
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now.
+  /**
+   * This function may be used to obtain the timer's current expiry time.
+   * Whether the timer has expired or not does not affect this value.
+   */
+  duration expires_from_now() const
+  {
+    return this->get_service().expires_from_now(this->get_implementation());
+  }
+
+  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+  /// to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration& expiry_time)
+  {
+    boost::system::error_code ec;
+    std::size_t s = this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
+    boost::asio::detail::throw_error(ec, "expires_from_now");
+    return s;
+  }
+
+  /// (Deprecated: Use expires_after().) Set the timer's expiry time relative
+  /// to now.
+  /**
+   * This function sets the expiry time. Any pending asynchronous wait
+   * operations will be cancelled. The handler for each cancelled operation will
+   * be invoked with the boost::asio::error::operation_aborted error code.
+   *
+   * @param expiry_time The expiry time to be used for the timer.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   *
+   * @return The number of asynchronous operations that were cancelled.
+   *
+   * @note If the timer has already expired when expires_from_now() is called,
+   * then the handlers for asynchronous wait operations will:
+   *
+   * @li have already been invoked; or
+   *
+   * @li have been queued for invocation in the near future.
+   *
+   * These handlers can no longer be cancelled, and therefore are passed an
+   * error code that indicates the successful completion of the wait operation.
+   */
+  std::size_t expires_from_now(const duration& expiry_time,
+      boost::system::error_code& ec)
+  {
+    return this->get_service().expires_from_now(
+        this->get_implementation(), expiry_time, ec);
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @throws boost::system::system_error Thrown on failure.
+   */
+  void wait()
+  {
+    boost::system::error_code ec;
+    this->get_service().wait(this->get_implementation(), ec);
+    boost::asio::detail::throw_error(ec, "wait");
+  }
+
+  /// Perform a blocking wait on the timer.
+  /**
+   * This function is used to wait for the timer to expire. This function
+   * blocks and does not return until the timer has expired.
+   *
+   * @param ec Set to indicate what error occurred, if any.
+   */
+  void wait(boost::system::error_code& ec)
+  {
+    this->get_service().wait(this->get_implementation(), ec);
+  }
+
+  /// Start an asynchronous wait on the timer.
+  /**
+   * This function may be used to initiate an asynchronous wait against the
+   * timer. It always returns immediately.
+   *
+   * For each call to async_wait(), the supplied handler will be called exactly
+   * once. The handler will be called when:
+   *
+   * @li The timer has expired.
+   *
+   * @li The timer was cancelled, in which case the handler is passed the error
+   * code boost::asio::error::operation_aborted.
+   *
+   * @param handler The handler to be called when the timer expires. Copies
+   * will be made of the handler as required. The function signature of the
+   * handler must be:
+   * @code void handler(
+   *   const boost::system::error_code& error // Result of operation.
+   * ); @endcode
+   * Regardless of whether the asynchronous operation completes immediately or
+   * not, the handler will not be invoked from within this function. Invocation
+   * of the handler will be performed in a manner equivalent to using
+   * boost::asio::io_context::post().
+   */
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    // If you get an error on the following line it means that your handler does
+    // not meet the documented type requirements for a WaitHandler.
+    BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    return this->get_service().async_wait(this->get_implementation(),
+        BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    this->get_service().async_wait(this->get_implementation(),
+        init.completion_handler);
+
+    return init.result.get();
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+  }
+
+private:
+  // Disallow copying and assignment.
+  basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
+  basic_waitable_timer& operator=(
+      const basic_waitable_timer&) BOOST_ASIO_DELETED;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# undef BOOST_ASIO_SVC_T
+#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP

+ 613 - 0
cpir-read/boost/boost/asio/bind_executor.hpp

@@ -0,0 +1,613 @@
+//
+// bind_executor.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BIND_EXECUTOR_HPP
+#define BOOST_ASIO_BIND_EXECUTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/detail/variadic_templates.hpp>
+#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/associated_allocator.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/is_executor.hpp>
+#include <boost/asio/uses_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+struct executor_binder_check
+{
+  typedef void type;
+};
+
+// Helper to automatically define nested typedef result_type.
+
+template <typename T, typename = void>
+struct executor_binder_result_type
+{
+protected:
+  typedef void result_type_or_void;
+};
+
+template <typename T>
+struct executor_binder_result_type<T,
+  typename executor_binder_check<typename T::result_type>::type>
+{
+  typedef typename T::result_type result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R>
+struct executor_binder_result_type<R(*)()>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R>
+struct executor_binder_result_type<R(&)()>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1>
+struct executor_binder_result_type<R(*)(A1)>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1>
+struct executor_binder_result_type<R(&)(A1)>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_result_type<R(*)(A1, A2)>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_result_type<R(&)(A1, A2)>
+{
+  typedef R result_type;
+protected:
+  typedef result_type result_type_or_void;
+};
+
+// Helper to automatically define nested typedef argument_type.
+
+template <typename T, typename = void>
+struct executor_binder_argument_type {};
+
+template <typename T>
+struct executor_binder_argument_type<T,
+  typename executor_binder_check<typename T::argument_type>::type>
+{
+  typedef typename T::argument_type argument_type;
+};
+
+template <typename R, typename A1>
+struct executor_binder_argument_type<R(*)(A1)>
+{
+  typedef A1 argument_type;
+};
+
+template <typename R, typename A1>
+struct executor_binder_argument_type<R(&)(A1)>
+{
+  typedef A1 argument_type;
+};
+
+// Helper to automatically define nested typedefs first_argument_type and
+// second_argument_type.
+
+template <typename T, typename = void>
+struct executor_binder_argument_types {};
+
+template <typename T>
+struct executor_binder_argument_types<T,
+  typename executor_binder_check<typename T::first_argument_type>::type>
+{
+  typedef typename T::first_argument_type first_argument_type;
+  typedef typename T::second_argument_type second_argument_type;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_argument_type<R(*)(A1, A2)>
+{
+  typedef A1 first_argument_type;
+  typedef A2 second_argument_type;
+};
+
+template <typename R, typename A1, typename A2>
+struct executor_binder_argument_type<R(&)(A1, A2)>
+{
+  typedef A1 first_argument_type;
+  typedef A2 second_argument_type;
+};
+
+// Helper to:
+// - Apply the empty base optimisation to the executor.
+// - Perform uses_executor construction of the target type, if required.
+
+template <typename T, typename Executor, bool UsesExecutor>
+class executor_binder_base;
+
+template <typename T, typename Executor>
+class executor_binder_base<T, Executor, true>
+  : protected Executor
+{
+protected:
+  template <typename E, typename U>
+  executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
+    : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
+      target_(executor_arg_t(), executor_, BOOST_ASIO_MOVE_CAST(U)(u))
+  {
+  }
+
+  Executor executor_;
+  T target_;
+};
+
+template <typename T, typename Executor>
+class executor_binder_base<T, Executor, false>
+{
+protected:
+  template <typename E, typename U>
+  executor_binder_base(BOOST_ASIO_MOVE_ARG(E) e, BOOST_ASIO_MOVE_ARG(U) u)
+    : executor_(BOOST_ASIO_MOVE_CAST(E)(e)),
+      target_(BOOST_ASIO_MOVE_CAST(U)(u))
+  {
+  }
+
+  Executor executor_;
+  T target_;
+};
+
+// Helper to enable SFINAE on zero-argument operator() below.
+
+template <typename T, typename = void>
+struct executor_binder_result_of0
+{
+  typedef void type;
+};
+
+template <typename T>
+struct executor_binder_result_of0<T,
+  typename executor_binder_check<typename result_of<T()>::type>::type>
+{
+  typedef typename result_of<T()>::type type;
+};
+
+} // namespace detail
+
+/// A call wrapper type to bind an executor of type @c Executor to an object of
+/// type @c T.
+template <typename T, typename Executor>
+class executor_binder
+#if !defined(GENERATING_DOCUMENTATION)
+  : public detail::executor_binder_result_type<T>,
+    public detail::executor_binder_argument_type<T>,
+    public detail::executor_binder_argument_types<T>,
+    private detail::executor_binder_base<
+      T, Executor, uses_executor<T, Executor>::value>
+#endif // !defined(GENERATING_DOCUMENTATION)
+{
+public:
+  /// The type of the target object.
+  typedef T target_type;
+
+  /// The type of the associated executor.
+  typedef Executor executor_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// The return type if a function.
+  /**
+   * The type of @c result_type is based on the type @c T of the wrapper's
+   * target object:
+   *
+   * @li if @c T is a pointer to function type, @c result_type is a synonym for
+   * the return type of @c T;
+   *
+   * @li if @c T is a class type with a member type @c result_type, then @c
+   * result_type is a synonym for @c T::result_type;
+   *
+   * @li otherwise @c result_type is not defined.
+   */
+  typedef see_below result_type;
+
+  /// The type of the function's argument.
+  /**
+   * The type of @c argument_type is based on the type @c T of the wrapper's
+   * target object:
+   *
+   * @li if @c T is a pointer to a function type accepting a single argument,
+   * @c argument_type is a synonym for the return type of @c T;
+   *
+   * @li if @c T is a class type with a member type @c argument_type, then @c
+   * argument_type is a synonym for @c T::argument_type;
+   *
+   * @li otherwise @c argument_type is not defined.
+   */
+  typedef see_below argument_type;
+
+  /// The type of the function's first argument.
+  /**
+   * The type of @c first_argument_type is based on the type @c T of the
+   * wrapper's target object:
+   *
+   * @li if @c T is a pointer to a function type accepting two arguments, @c
+   * first_argument_type is a synonym for the return type of @c T;
+   *
+   * @li if @c T is a class type with a member type @c first_argument_type,
+   * then @c first_argument_type is a synonym for @c T::first_argument_type;
+   *
+   * @li otherwise @c first_argument_type is not defined.
+   */
+  typedef see_below first_argument_type;
+
+  /// The type of the function's second argument.
+  /**
+   * The type of @c second_argument_type is based on the type @c T of the
+   * wrapper's target object:
+   *
+   * @li if @c T is a pointer to a function type accepting two arguments, @c
+   * second_argument_type is a synonym for the return type of @c T;
+   *
+   * @li if @c T is a class type with a member type @c first_argument_type,
+   * then @c second_argument_type is a synonym for @c T::second_argument_type;
+   *
+   * @li otherwise @c second_argument_type is not defined.
+   */
+  typedef see_below second_argument_type;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// Construct an executor wrapper for the specified object.
+  /**
+   * This constructor is only valid if the type @c T is constructible from type
+   * @c U.
+   */
+  template <typename U>
+  executor_binder(executor_arg_t, const executor_type& e,
+      BOOST_ASIO_MOVE_ARG(U) u)
+    : base_type(e, BOOST_ASIO_MOVE_CAST(U)(u))
+  {
+  }
+
+  /// Copy constructor.
+  executor_binder(const executor_binder& other)
+    : base_type(other.get_executor(), other.get())
+  {
+  }
+
+  /// Construct a copy, but specify a different executor.
+  executor_binder(executor_arg_t, const executor_type& e,
+      const executor_binder& other)
+    : base_type(e, other.get())
+  {
+  }
+
+  /// Construct a copy of a different executor wrapper type.
+  /**
+   * This constructor is only valid if the @c Executor type is constructible
+   * from type @c OtherExecutor, and the type @c T is constructible from type
+   * @c U.
+   */
+  template <typename U, typename OtherExecutor>
+  executor_binder(const executor_binder<U, OtherExecutor>& other)
+    : base_type(other.get_executor(), other.get())
+  {
+  }
+
+  /// Construct a copy of a different executor wrapper type, but specify a
+  /// different executor.
+  /**
+   * This constructor is only valid if the type @c T is constructible from type
+   * @c U.
+   */
+  template <typename U, typename OtherExecutor>
+  executor_binder(executor_arg_t, const executor_type& e,
+      const executor_binder<U, OtherExecutor>& other)
+    : base_type(e, other.get())
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Move constructor.
+  executor_binder(executor_binder&& other)
+    : base_type(BOOST_ASIO_MOVE_CAST(executor_type)(other.get_executor()),
+        BOOST_ASIO_MOVE_CAST(T)(other.get()))
+  {
+  }
+
+  /// Move construct the target object, but specify a different executor.
+  executor_binder(executor_arg_t, const executor_type& e,
+      executor_binder&& other)
+    : base_type(e, BOOST_ASIO_MOVE_CAST(T)(other.get()))
+  {
+  }
+
+  /// Move construct from a different executor wrapper type.
+  template <typename U, typename OtherExecutor>
+  executor_binder(executor_binder<U, OtherExecutor>&& other)
+    : base_type(BOOST_ASIO_MOVE_CAST(OtherExecutor)(other.get_executor()),
+        BOOST_ASIO_MOVE_CAST(U)(other.get()))
+  {
+  }
+
+  /// Move construct from a different executor wrapper type, but specify a
+  /// different executor.
+  template <typename U, typename OtherExecutor>
+  executor_binder(executor_arg_t, const executor_type& e,
+      executor_binder<U, OtherExecutor>&& other)
+    : base_type(e, BOOST_ASIO_MOVE_CAST(U)(other.get()))
+  {
+  }
+
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destructor.
+  ~executor_binder()
+  {
+  }
+
+  /// Obtain a reference to the target object.
+  target_type& get() BOOST_ASIO_NOEXCEPT
+  {
+    return this->target_;
+  }
+
+  /// Obtain a reference to the target object.
+  const target_type& get() const BOOST_ASIO_NOEXCEPT
+  {
+    return this->target_;
+  }
+
+  /// Obtain the associated executor.
+  executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+  {
+    return this->executor_;
+  }
+
+#if defined(GENERATING_DOCUMENTATION)
+
+  template <typename... Args> auto operator()(Args&& ...);
+  template <typename... Args> auto operator()(Args&& ...) const;
+
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+  /// Forwarding function call operator.
+  template <typename... Args>
+  typename result_of<T(Args...)>::type operator()(
+      BOOST_ASIO_MOVE_ARG(Args)... args)
+  {
+    return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+  }
+
+  /// Forwarding function call operator.
+  template <typename... Args>
+  typename result_of<T(Args...)>::type operator()(
+      BOOST_ASIO_MOVE_ARG(Args)... args) const
+  {
+    return this->target_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+  }
+
+#elif defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+  typename detail::executor_binder_result_of0<T>::type operator()()
+  {
+    return this->target_();
+  }
+
+  typename detail::executor_binder_result_of0<T>::type operator()() const
+  {
+    return this->target_();
+  }
+
+#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
+      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+  { \
+    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  typename result_of<T(BOOST_ASIO_VARIADIC_TARGS(n))>::type operator()( \
+      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
+  { \
+    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  /**/
+  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
+#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
+
+#else // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+  typedef typename detail::executor_binder_result_type<T>::result_type_or_void
+    result_type_or_void;
+
+  result_type_or_void operator()()
+  {
+    return this->target_();
+  }
+
+  result_type_or_void operator()() const
+  {
+    return this->target_();
+  }
+
+#define BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF(n) \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  result_type_or_void operator()( \
+      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+  { \
+    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  \
+  template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+  result_type_or_void operator()( \
+      BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) const \
+  { \
+    return this->target_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+  } \
+  /**/
+  BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF)
+#undef BOOST_ASIO_PRIVATE_BIND_EXECUTOR_CALL_DEF
+
+#endif // defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS) && !defined(_MSC_VER)
+
+private:
+  typedef detail::executor_binder_base<T, Executor,
+    uses_executor<T, Executor>::value> base_type;
+};
+
+/// Associate an object of type @c T with an executor of type @c Executor.
+template <typename Executor, typename T>
+inline executor_binder<typename decay<T>::type, Executor>
+bind_executor(const Executor& ex, BOOST_ASIO_MOVE_ARG(T) t,
+    typename enable_if<is_executor<Executor>::value>::type* = 0)
+{
+  return executor_binder<typename decay<T>::type, Executor>(
+      executor_arg_t(), ex, BOOST_ASIO_MOVE_CAST(T)(t));
+}
+
+/// Associate an object of type @c T with an execution context's executor.
+template <typename ExecutionContext, typename T>
+inline executor_binder<typename decay<T>::type,
+  typename ExecutionContext::executor_type>
+bind_executor(ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(T) t,
+    typename enable_if<is_convertible<
+      ExecutionContext&, execution_context&>::value>::type* = 0)
+{
+  return executor_binder<typename decay<T>::type,
+    typename ExecutionContext::executor_type>(
+      executor_arg_t(), ctx.get_executor(), BOOST_ASIO_MOVE_CAST(T)(t));
+}
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename T, typename Executor>
+struct uses_executor<executor_binder<T, Executor>, Executor>
+  : true_type {};
+
+template <typename T, typename Executor, typename Signature>
+class async_result<executor_binder<T, Executor>, Signature>
+{
+public:
+  typedef executor_binder<
+    typename async_result<T, Signature>::completion_handler_type, Executor>
+      completion_handler_type;
+
+  typedef typename async_result<T, Signature>::return_type return_type;
+
+  explicit async_result(executor_binder<T, Executor>& b)
+    : target_(b.get())
+  {
+  }
+
+  return_type get()
+  {
+    return target_.get();
+  }
+
+private:
+  async_result(const async_result&) BOOST_ASIO_DELETED;
+  async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
+
+  async_result<T, Signature> target_;
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename T, typename Executor, typename Signature>
+struct handler_type<executor_binder<T, Executor>, Signature>
+{
+  typedef executor_binder<
+    typename handler_type<T, Signature>::type, Executor> type;
+};
+
+template <typename T, typename Executor>
+class async_result<executor_binder<T, Executor> >
+{
+public:
+  typedef typename async_result<T>::type type;
+
+  explicit async_result(executor_binder<T, Executor>& b)
+    : target_(b.get())
+  {
+  }
+
+  type get()
+  {
+    return target_.get();
+  }
+
+private:
+  async_result<T> target_;
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename T, typename Executor, typename Allocator>
+struct associated_allocator<executor_binder<T, Executor>, Allocator>
+{
+  typedef typename associated_allocator<T, Allocator>::type type;
+
+  static type get(const executor_binder<T, Executor>& b,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<T, Allocator>::get(b.get(), a);
+  }
+};
+
+template <typename T, typename Executor, typename Executor1>
+struct associated_executor<executor_binder<T, Executor>, Executor1>
+{
+  typedef Executor type;
+
+  static type get(const executor_binder<T, Executor>& b,
+      const Executor1& = Executor1()) BOOST_ASIO_NOEXCEPT
+  {
+    return b.get_executor();
+  }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BIND_EXECUTOR_HPP

+ 2164 - 0
cpir-read/boost/boost/asio/buffer.hpp

@@ -0,0 +1,2164 @@
+//
+// buffer.hpp
+// ~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFER_HPP
+#define BOOST_ASIO_BUFFER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <cstring>
+#include <limits>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <boost/asio/detail/array_fwd.hpp>
+#include <boost/asio/detail/is_buffer_sequence.hpp>
+#include <boost/asio/detail/string_view.hpp>
+#include <boost/asio/detail/throw_exception.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
+# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
+#  if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
+#   define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+#  endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
+# endif // defined(_HAS_ITERATOR_DEBUGGING)
+#endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1700)
+
+#if defined(__GNUC__)
+# if defined(_GLIBCXX_DEBUG)
+#  if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
+#   define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+#  endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
+# endif // defined(_GLIBCXX_DEBUG)
+#endif // defined(__GNUC__)
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+# include <boost/asio/detail/functional.hpp>
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+#if defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
+# include <boost/detail/workaround.hpp>
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
+    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+#  define BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND
+# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
+        // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+#endif // defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
+
+#if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
+# include <boost/asio/detail/type_traits.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+class mutable_buffer;
+class const_buffer;
+
+/// Holds a buffer that can be modified.
+/**
+ * The mutable_buffer class provides a safe representation of a buffer that can
+ * be modified. It does not own the underlying data, and so is cheap to copy or
+ * assign.
+ *
+ * @par Accessing Buffer Contents
+ *
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
+ *
+ * @code boost::asio::mutable_buffer b1 = ...;
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+ * @endcode
+ *
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
+ */
+class mutable_buffer
+{
+public:
+  /// Construct an empty buffer.
+  mutable_buffer() BOOST_ASIO_NOEXCEPT
+    : data_(0),
+      size_(0)
+  {
+  }
+
+  /// Construct a buffer to represent a given memory range.
+  mutable_buffer(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
+    : data_(data),
+      size_(size)
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  mutable_buffer(void* data, std::size_t size,
+      boost::asio::detail::function<void()> debug_check)
+    : data_(data),
+      size_(size),
+      debug_check_(debug_check)
+  {
+  }
+
+  const boost::asio::detail::function<void()>& get_debug_check() const
+  {
+    return debug_check_;
+  }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+  /// Get a pointer to the beginning of the memory range.
+  void* data() const BOOST_ASIO_NOEXCEPT
+  {
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+    if (size_ && debug_check_)
+      debug_check_();
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+    return data_;
+  }
+
+  /// Get the size of the memory range.
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return size_;
+  }
+
+  /// Move the start of the buffer by the specified number of bytes.
+  mutable_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT
+  {
+    std::size_t offset = n < size_ ? n : size_;
+    data_ = static_cast<char*>(data_) + offset;
+    size_ -= offset;
+    return *this;
+  }
+
+private:
+  void* data_;
+  std::size_t size_;
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  boost::asio::detail::function<void()> debug_check_;
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// (Deprecated: Use mutable_buffer.) Adapts a single modifiable buffer so that
+/// it meets the requirements of the MutableBufferSequence concept.
+class mutable_buffers_1
+  : public mutable_buffer
+{
+public:
+  /// The type for each element in the list of buffers.
+  typedef mutable_buffer value_type;
+
+  /// A random-access iterator type that may be used to read elements.
+  typedef const mutable_buffer* const_iterator;
+
+  /// Construct to represent a given memory range.
+  mutable_buffers_1(void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
+    : mutable_buffer(data, size)
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  mutable_buffers_1(void* data, std::size_t size,
+      boost::asio::detail::function<void()> debug_check)
+    : mutable_buffer(data, size, debug_check)
+  {
+  }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+  /// Construct to represent a single modifiable buffer.
+  explicit mutable_buffers_1(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+    : mutable_buffer(b)
+  {
+  }
+
+  /// Get a random-access iterator to the first element.
+  const_iterator begin() const BOOST_ASIO_NOEXCEPT
+  {
+    return this;
+  }
+
+  /// Get a random-access iterator for one past the last element.
+  const_iterator end() const BOOST_ASIO_NOEXCEPT
+  {
+    return begin() + 1;
+  }
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Holds a buffer that cannot be modified.
+/**
+ * The const_buffer class provides a safe representation of a buffer that cannot
+ * be modified. It does not own the underlying data, and so is cheap to copy or
+ * assign.
+ *
+ * @par Accessing Buffer Contents
+ *
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
+ *
+ * @code boost::asio::const_buffer b1 = ...;
+ * std::size_t s1 = b1.size();
+ * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
+ * @endcode
+ *
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
+ */
+class const_buffer
+{
+public:
+  /// Construct an empty buffer.
+  const_buffer() BOOST_ASIO_NOEXCEPT
+    : data_(0),
+      size_(0)
+  {
+  }
+
+  /// Construct a buffer to represent a given memory range.
+  const_buffer(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
+    : data_(data),
+      size_(size)
+  {
+  }
+
+  /// Construct a non-modifiable buffer from a modifiable one.
+  const_buffer(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+    : data_(b.data()),
+      size_(b.size())
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , debug_check_(b.get_debug_check())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  const_buffer(const void* data, std::size_t size,
+      boost::asio::detail::function<void()> debug_check)
+    : data_(data),
+      size_(size),
+      debug_check_(debug_check)
+  {
+  }
+
+  const boost::asio::detail::function<void()>& get_debug_check() const
+  {
+    return debug_check_;
+  }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+  /// Get a pointer to the beginning of the memory range.
+  const void* data() const BOOST_ASIO_NOEXCEPT
+  {
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+    if (size_ && debug_check_)
+      debug_check_();
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+    return data_;
+  }
+
+  /// Get the size of the memory range.
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return size_;
+  }
+
+  /// Move the start of the buffer by the specified number of bytes.
+  const_buffer& operator+=(std::size_t n) BOOST_ASIO_NOEXCEPT
+  {
+    std::size_t offset = n < size_ ? n : size_;
+    data_ = static_cast<const char*>(data_) + offset;
+    size_ -= offset;
+    return *this;
+  }
+
+private:
+  const void* data_;
+  std::size_t size_;
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  boost::asio::detail::function<void()> debug_check_;
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// (Deprecated: Use const_buffer.) Adapts a single non-modifiable buffer so
+/// that it meets the requirements of the ConstBufferSequence concept.
+class const_buffers_1
+  : public const_buffer
+{
+public:
+  /// The type for each element in the list of buffers.
+  typedef const_buffer value_type;
+
+  /// A random-access iterator type that may be used to read elements.
+  typedef const const_buffer* const_iterator;
+
+  /// Construct to represent a given memory range.
+  const_buffers_1(const void* data, std::size_t size) BOOST_ASIO_NOEXCEPT
+    : const_buffer(data, size)
+  {
+  }
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+  const_buffers_1(const void* data, std::size_t size,
+      boost::asio::detail::function<void()> debug_check)
+    : const_buffer(data, size, debug_check)
+  {
+  }
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+  /// Construct to represent a single non-modifiable buffer.
+  explicit const_buffers_1(const const_buffer& b) BOOST_ASIO_NOEXCEPT
+    : const_buffer(b)
+  {
+  }
+
+  /// Get a random-access iterator to the first element.
+  const_iterator begin() const BOOST_ASIO_NOEXCEPT
+  {
+    return this;
+  }
+
+  /// Get a random-access iterator for one past the last element.
+  const_iterator end() const BOOST_ASIO_NOEXCEPT
+  {
+    return begin() + 1;
+  }
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Trait to determine whether a type satisfies the MutableBufferSequence
+/// requirements.
+template <typename T>
+struct is_mutable_buffer_sequence
+#if defined(GENERATING_DOCUMENTATION)
+  : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+  : boost::asio::detail::is_buffer_sequence<T, mutable_buffer>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// Trait to determine whether a type satisfies the ConstBufferSequence
+/// requirements.
+template <typename T>
+struct is_const_buffer_sequence
+#if defined(GENERATING_DOCUMENTATION)
+  : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+  : boost::asio::detail::is_buffer_sequence<T, const_buffer>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
+template <typename T>
+struct is_dynamic_buffer
+#if defined(GENERATING_DOCUMENTATION)
+  : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+  : boost::asio::detail::is_dynamic_buffer<T>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+
+/// (Deprecated: Use the socket/descriptor wait() and async_wait() member
+/// functions.) An implementation of both the ConstBufferSequence and
+/// MutableBufferSequence concepts to represent a null buffer sequence.
+class null_buffers
+{
+public:
+  /// The type for each element in the list of buffers.
+  typedef mutable_buffer value_type;
+
+  /// A random-access iterator type that may be used to read elements.
+  typedef const mutable_buffer* const_iterator;
+
+  /// Get a random-access iterator to the first element.
+  const_iterator begin() const BOOST_ASIO_NOEXCEPT
+  {
+    return &buf_;
+  }
+
+  /// Get a random-access iterator for one past the last element.
+  const_iterator end() const BOOST_ASIO_NOEXCEPT
+  {
+    return &buf_;
+  }
+
+private:
+  mutable_buffer buf_;
+};
+
+/** @defgroup buffer_sequence_begin boost::asio::buffer_sequence_begin
+ *
+ * @brief The boost::asio::buffer_sequence_begin function returns an iterator
+ * pointing to the first element in a buffer sequence.
+ */
+/*@{*/
+
+/// Get an iterator to the first element in a buffer sequence.
+inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b)
+{
+  return &b;
+}
+
+/// Get an iterator to the first element in a buffer sequence.
+inline const const_buffer* buffer_sequence_begin(const const_buffer& b)
+{
+  return &b;
+}
+
+#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/// Get an iterator to the first element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_begin(C& c) -> decltype(c.begin())
+{
+  return c.begin();
+}
+
+/// Get an iterator to the first element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
+{
+  return c.begin();
+}
+
+#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+template <typename C>
+inline typename C::iterator buffer_sequence_begin(C& c)
+{
+  return c.begin();
+}
+
+template <typename C>
+inline typename C::const_iterator buffer_sequence_begin(const C& c)
+{
+  return c.begin();
+}
+
+#endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+/** @defgroup buffer_sequence_end boost::asio::buffer_sequence_end
+ *
+ * @brief The boost::asio::buffer_sequence_end function returns an iterator
+ * pointing to one past the end element in a buffer sequence.
+ */
+/*@{*/
+
+/// Get an iterator to one past the end element in a buffer sequence.
+inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b)
+{
+  return &b + 1;
+}
+
+/// Get an iterator to one past the end element in a buffer sequence.
+inline const const_buffer* buffer_sequence_end(const const_buffer& b)
+{
+  return &b + 1;
+}
+
+#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/// Get an iterator to one past the end element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_end(C& c) -> decltype(c.end())
+{
+  return c.end();
+}
+
+/// Get an iterator to one past the end element in a buffer sequence.
+template <typename C>
+inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
+{
+  return c.end();
+}
+
+#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+template <typename C>
+inline typename C::iterator buffer_sequence_end(C& c)
+{
+  return c.end();
+}
+
+template <typename C>
+inline typename C::const_iterator buffer_sequence_end(const C& c)
+{
+  return c.end();
+}
+
+#endif // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+namespace detail {
+
+// Tag types used to select appropriately optimised overloads.
+struct one_buffer {};
+struct multiple_buffers {};
+
+// Helper trait to detect single buffers.
+template <typename BufferSequence>
+struct buffer_sequence_cardinality :
+  conditional<
+    is_same<BufferSequence, mutable_buffer>::value
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+      || is_same<BufferSequence, mutable_buffers_1>::value
+      || is_same<BufferSequence, const_buffers_1>::value
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+      || is_same<BufferSequence, const_buffer>::value,
+    one_buffer, multiple_buffers>::type {};
+
+template <typename Iterator>
+inline std::size_t buffer_size(one_buffer,
+    Iterator begin, Iterator) BOOST_ASIO_NOEXCEPT
+{
+  return const_buffer(*begin).size();
+}
+
+template <typename Iterator>
+inline std::size_t buffer_size(multiple_buffers,
+    Iterator begin, Iterator end) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t total_buffer_size = 0;
+
+  Iterator iter = begin;
+  for (; iter != end; ++iter)
+  {
+    const_buffer b(*iter);
+    total_buffer_size += b.size();
+  }
+
+  return total_buffer_size;
+}
+
+} // namespace detail
+
+/// Get the total number of bytes in a buffer sequence.
+/**
+ * The @c buffer_size function determines the total size of all buffers in the
+ * buffer sequence, as if computed as follows:
+ *
+ * @code size_t total_size = 0;
+ * auto i = boost::asio::buffer_sequence_begin(buffers);
+ * auto end = boost::asio::buffer_sequence_end(buffers);
+ * for (; i != end; ++i)
+ * {
+ *   const_buffer b(*i);
+ *   total_size += b.size();
+ * }
+ * return total_size; @endcode
+ *
+ * The @c BufferSequence template parameter may meet either of the @c
+ * ConstBufferSequence or @c MutableBufferSequence type requirements.
+ */
+template <typename BufferSequence>
+inline std::size_t buffer_size(const BufferSequence& b) BOOST_ASIO_NOEXCEPT
+{
+  return detail::buffer_size(
+      detail::buffer_sequence_cardinality<BufferSequence>(),
+      boost::asio::buffer_sequence_begin(b),
+      boost::asio::buffer_sequence_end(b));
+}
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/** @defgroup buffer_cast boost::asio::buffer_cast
+ *
+ * @brief (Deprecated: Use the @c data() member function.) The
+ * boost::asio::buffer_cast function is used to obtain a pointer to the
+ * underlying memory region associated with a buffer.
+ *
+ * @par Examples:
+ *
+ * To access the memory of a non-modifiable buffer, use:
+ * @code boost::asio::const_buffer b1 = ...;
+ * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
+ * @endcode
+ *
+ * To access the memory of a modifiable buffer, use:
+ * @code boost::asio::mutable_buffer b2 = ...;
+ * unsigned char* p2 = boost::asio::buffer_cast<unsigned char*>(b2);
+ * @endcode
+ *
+ * The boost::asio::buffer_cast function permits violations of type safety, so
+ * uses of it in application code should be carefully considered.
+ */
+/*@{*/
+
+/// Cast a non-modifiable buffer to a specified pointer to POD type.
+template <typename PointerToPodType>
+inline PointerToPodType buffer_cast(const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return static_cast<PointerToPodType>(b.data());
+}
+
+/// Cast a non-modifiable buffer to a specified pointer to POD type.
+template <typename PointerToPodType>
+inline PointerToPodType buffer_cast(const const_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return static_cast<PointerToPodType>(b.data());
+}
+
+/*@}*/
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Create a new modifiable buffer that is offset from the start of another.
+/**
+ * @relates mutable_buffer
+ */
+inline mutable_buffer operator+(const mutable_buffer& b,
+    std::size_t n) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t offset = n < b.size() ? n : b.size();
+  char* new_data = static_cast<char*>(b.data()) + offset;
+  std::size_t new_size = b.size() - offset;
+  return mutable_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new modifiable buffer that is offset from the start of another.
+/**
+ * @relates mutable_buffer
+ */
+inline mutable_buffer operator+(std::size_t n,
+    const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return b + n;
+}
+
+/// Create a new non-modifiable buffer that is offset from the start of another.
+/**
+ * @relates const_buffer
+ */
+inline const_buffer operator+(const const_buffer& b,
+    std::size_t n) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t offset = n < b.size() ? n : b.size();
+  const char* new_data = static_cast<const char*>(b.data()) + offset;
+  std::size_t new_size = b.size() - offset;
+  return const_buffer(new_data, new_size
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that is offset from the start of another.
+/**
+ * @relates const_buffer
+ */
+inline const_buffer operator+(std::size_t n,
+    const const_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return b + n;
+}
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+namespace detail {
+
+template <typename Iterator>
+class buffer_debug_check
+{
+public:
+  buffer_debug_check(Iterator iter)
+    : iter_(iter)
+  {
+  }
+
+  ~buffer_debug_check()
+  {
+#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
+    // MSVC 8's string iterator checking may crash in a std::string::iterator
+    // object's destructor when the iterator points to an already-destroyed
+    // std::string object, unless the iterator is cleared first.
+    iter_ = Iterator();
+#endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
+  }
+
+  void operator()()
+  {
+    (void)*iter_;
+  }
+
+private:
+  Iterator iter_;
+};
+
+} // namespace detail
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+
+/** @defgroup buffer boost::asio::buffer
+ *
+ * @brief The boost::asio::buffer function is used to create a buffer object to
+ * represent raw memory, an array of POD elements, a vector of POD elements,
+ * or a std::string.
+ *
+ * A buffer object represents a contiguous region of memory as a 2-tuple
+ * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,
+ * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a
+ * tuple of the form <tt>{const void*, size_t}</tt> specifies a const
+ * (non-modifiable) region of memory. These two forms correspond to the classes
+ * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion
+ * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the
+ * opposite conversion is not permitted.
+ *
+ * The simplest use case involves reading or writing a single buffer of a
+ * specified size:
+ *
+ * @code sock.send(boost::asio::buffer(data, size)); @endcode
+ *
+ * In the above example, the return value of boost::asio::buffer meets the
+ * requirements of the ConstBufferSequence concept so that it may be directly
+ * passed to the socket's write function. A buffer created for modifiable
+ * memory also meets the requirements of the MutableBufferSequence concept.
+ *
+ * An individual buffer may be created from a builtin array, std::vector,
+ * std::array or boost::array of POD elements. This helps prevent buffer
+ * overruns by automatically determining the size of the buffer:
+ *
+ * @code char d1[128];
+ * size_t bytes_transferred = sock.receive(boost::asio::buffer(d1));
+ *
+ * std::vector<char> d2(128);
+ * bytes_transferred = sock.receive(boost::asio::buffer(d2));
+ *
+ * std::array<char, 128> d3;
+ * bytes_transferred = sock.receive(boost::asio::buffer(d3));
+ *
+ * boost::array<char, 128> d4;
+ * bytes_transferred = sock.receive(boost::asio::buffer(d4)); @endcode
+ *
+ * In all three cases above, the buffers created are exactly 128 bytes long.
+ * Note that a vector is @e never automatically resized when creating or using
+ * a buffer. The buffer size is determined using the vector's <tt>size()</tt>
+ * member function, and not its capacity.
+ *
+ * @par Accessing Buffer Contents
+ *
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
+ *
+ * @code boost::asio::mutable_buffer b1 = ...;
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
+ *
+ * boost::asio::const_buffer b2 = ...;
+ * std::size_t s2 = b2.size();
+ * const void* p2 = b2.data(); @endcode
+ *
+ * The @c data() member function permits violations of type safety, so
+ * uses of it in application code should be carefully considered.
+ *
+ * For convenience, a @ref buffer_size function is provided that works with
+ * both buffers and buffer sequences (that is, types meeting the
+ * ConstBufferSequence or MutableBufferSequence type requirements). In this
+ * case, the function returns the total size of all buffers in the sequence.
+ *
+ * @par Buffer Copying
+ *
+ * The @ref buffer_copy function may be used to copy raw bytes between
+ * individual buffers and buffer sequences.
+*
+ * In particular, when used with the @ref buffer_size function, the @ref
+ * buffer_copy function can be used to linearise a sequence of buffers. For
+ * example:
+ *
+ * @code vector<const_buffer> buffers = ...;
+ *
+ * vector<unsigned char> data(boost::asio::buffer_size(buffers));
+ * boost::asio::buffer_copy(boost::asio::buffer(data), buffers); @endcode
+ *
+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
+ * consequently it cannot be used to copy between overlapping memory regions.
+ *
+ * @par Buffer Invalidation
+ *
+ * A buffer object does not have any ownership of the memory it refers to. It
+ * is the responsibility of the application to ensure the memory region remains
+ * valid until it is no longer required for an I/O operation. When the memory
+ * is no longer available, the buffer is said to have been invalidated.
+ *
+ * For the boost::asio::buffer overloads that accept an argument of type
+ * std::vector, the buffer objects returned are invalidated by any vector
+ * operation that also invalidates all references, pointers and iterators
+ * referring to the elements in the sequence (C++ Std, 23.2.4)
+ *
+ * For the boost::asio::buffer overloads that accept an argument of type
+ * std::basic_string, the buffer objects returned are invalidated according to
+ * the rules defined for invalidation of references, pointers and iterators
+ * referring to elements of the sequence (C++ Std, 21.3).
+ *
+ * @par Buffer Arithmetic
+ *
+ * Buffer objects may be manipulated using simple arithmetic in a safe way
+ * which helps prevent buffer overruns. Consider an array initialised as
+ * follows:
+ *
+ * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode
+ *
+ * A buffer object @c b1 created using:
+ *
+ * @code b1 = boost::asio::buffer(a); @endcode
+ *
+ * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An
+ * optional second argument to the boost::asio::buffer function may be used to
+ * limit the size, in bytes, of the buffer:
+ *
+ * @code b2 = boost::asio::buffer(a, 3); @endcode
+ *
+ * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the
+ * size argument exceeds the actual size of the array, the size of the buffer
+ * object created will be limited to the array size.
+ *
+ * An offset may be applied to an existing buffer to create a new one:
+ *
+ * @code b3 = b1 + 2; @endcode
+ *
+ * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset
+ * exceeds the size of the existing buffer, the newly created buffer will be
+ * empty.
+ *
+ * Both an offset and size may be specified to create a buffer that corresponds
+ * to a specific range of bytes within an existing buffer:
+ *
+ * @code b4 = boost::asio::buffer(b1 + 1, 3); @endcode
+ *
+ * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.
+ *
+ * @par Buffers and Scatter-Gather I/O
+ *
+ * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
+ * buffer objects may be assigned into a container that supports the
+ * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
+ *
+ * @code
+ * char d1[128];
+ * std::vector<char> d2(128);
+ * boost::array<char, 128> d3;
+ *
+ * boost::array<mutable_buffer, 3> bufs1 = {
+ *   boost::asio::buffer(d1),
+ *   boost::asio::buffer(d2),
+ *   boost::asio::buffer(d3) };
+ * bytes_transferred = sock.receive(bufs1);
+ *
+ * std::vector<const_buffer> bufs2;
+ * bufs2.push_back(boost::asio::buffer(d1));
+ * bufs2.push_back(boost::asio::buffer(d2));
+ * bufs2.push_back(boost::asio::buffer(d3));
+ * bytes_transferred = sock.send(bufs2); @endcode
+ */
+/*@{*/
+
+#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_MUTABLE_BUFFER mutable_buffer
+# define BOOST_ASIO_CONST_BUFFER const_buffer
+#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_1
+# define BOOST_ASIO_CONST_BUFFER const_buffers_1
+#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer from an existing buffer.
+/**
+ * @returns <tt>mutable_buffer(b)</tt>.
+ */
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    const mutable_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(b);
+}
+
+/// Create a new modifiable buffer from an existing buffer.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     b.data(),
+ *     min(b.size(), max_size_in_bytes)); @endcode
+ */
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(const mutable_buffer& b,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(
+      mutable_buffer(b.data(),
+        b.size() < max_size_in_bytes
+        ? b.size() : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+        , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+        ));
+}
+
+/// Create a new non-modifiable buffer from an existing buffer.
+/**
+ * @returns <tt>const_buffer(b)</tt>.
+ */
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const const_buffer& b) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(b);
+}
+
+/// Create a new non-modifiable buffer from an existing buffer.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     b.data(),
+ *     min(b.size(), max_size_in_bytes)); @endcode
+ */
+inline BOOST_ASIO_CONST_BUFFER buffer(const const_buffer& b,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(b.data(),
+      b.size() < max_size_in_bytes
+      ? b.size() : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , b.get_debug_check()
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new modifiable buffer that represents the given memory range.
+/**
+ * @returns <tt>mutable_buffer(data, size_in_bytes)</tt>.
+ */
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(void* data,
+    std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data, size_in_bytes);
+}
+
+/// Create a new non-modifiable buffer that represents the given memory range.
+/**
+ * @returns <tt>const_buffer(data, size_in_bytes)</tt>.
+ */
+inline BOOST_ASIO_CONST_BUFFER buffer(const void* data,
+    std::size_t size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data, size_in_bytes);
+}
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     static_cast<void*>(data),
+ *     N * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data, N * sizeof(PodType));
+}
+ 
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     static_cast<void*>(data),
+ *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(PodType (&data)[N],
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data,
+      N * sizeof(PodType) < max_size_in_bytes
+      ? N * sizeof(PodType) : max_size_in_bytes);
+}
+ 
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     static_cast<const void*>(data),
+ *     N * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const PodType (&data)[N]) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data, N * sizeof(PodType));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     static_cast<const void*>(data),
+ *     min(N * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(const PodType (&data)[N],
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data,
+      N * sizeof(PodType) < max_size_in_bytes
+      ? N * sizeof(PodType) : max_size_in_bytes);
+}
+
+#if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
+
+// Borland C++ and Sun Studio think the overloads:
+//
+//   unspecified buffer(boost::array<PodType, N>& array ...);
+//
+// and
+//
+//   unspecified buffer(boost::array<const PodType, N>& array ...);
+//
+// are ambiguous. This will be worked around by using a buffer_types traits
+// class that contains typedefs for the appropriate buffer and container
+// classes, based on whether PodType is const or non-const.
+
+namespace detail {
+
+template <bool IsConst>
+struct buffer_types_base;
+
+template <>
+struct buffer_types_base<false>
+{
+  typedef mutable_buffer buffer_type;
+  typedef BOOST_ASIO_MUTABLE_BUFFER container_type;
+};
+
+template <>
+struct buffer_types_base<true>
+{
+  typedef const_buffer buffer_type;
+  typedef BOOST_ASIO_CONST_BUFFER container_type;
+};
+
+template <typename PodType>
+struct buffer_types
+  : public buffer_types_base<is_const<PodType>::value>
+{
+};
+
+} // namespace detail
+
+template <typename PodType, std::size_t N>
+inline typename detail::buffer_types<PodType>::container_type
+buffer(boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
+    buffer_type;
+  typedef typename boost::asio::detail::buffer_types<PodType>::container_type
+    container_type;
+  return container_type(
+      buffer_type(data.c_array(), data.size() * sizeof(PodType)));
+}
+
+template <typename PodType, std::size_t N>
+inline typename detail::buffer_types<PodType>::container_type
+buffer(boost::array<PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
+    buffer_type;
+  typedef typename boost::asio::detail::buffer_types<PodType>::container_type
+    container_type;
+  return container_type(
+      buffer_type(data.c_array(),
+        data.size() * sizeof(PodType) < max_size_in_bytes
+        ? data.size() * sizeof(PodType) : max_size_in_bytes));
+}
+
+#else // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(
+      data.c_array(), data.size() * sizeof(PodType));
+}
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(boost::array<PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.c_array(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    boost::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(boost::array<const PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+#endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const boost::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(const boost::array<PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.data(), data.size() * sizeof(PodType));
+}
+
+/// Create a new modifiable buffer that represents the given POD array.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::array<PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.data(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    std::array<const PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(std::array<const PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     data.size() * sizeof(PodType)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const std::array<PodType, N>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(PodType));
+}
+
+/// Create a new non-modifiable buffer that represents the given POD array.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ */
+template <typename PodType, std::size_t N>
+inline BOOST_ASIO_CONST_BUFFER buffer(const std::array<PodType, N>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(),
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes);
+}
+
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer that represents the given POD vector.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     data.size() * sizeof(PodType)); @endcode
+ *
+ * @note The buffer is invalidated by any vector operation that would also
+ * invalidate iterators.
+ */
+template <typename PodType, typename Allocator>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(
+      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::vector<PodType, Allocator>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new modifiable buffer that represents the given POD vector.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ *
+ * @note The buffer is invalidated by any vector operation that would also
+ * invalidate iterators.
+ */
+template <typename PodType, typename Allocator>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(std::vector<PodType, Allocator>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::vector<PodType, Allocator>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given POD vector.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     data.size() * sizeof(PodType)); @endcode
+ *
+ * @note The buffer is invalidated by any vector operation that would also
+ * invalidate iterators.
+ */
+template <typename PodType, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const std::vector<PodType, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(
+      data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::vector<PodType, Allocator>::const_iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given POD vector.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
+ *
+ * @note The buffer is invalidated by any vector operation that would also
+ * invalidate iterators.
+ */
+template <typename PodType, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const std::vector<PodType, Allocator>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(PodType) < max_size_in_bytes
+      ? data.size() * sizeof(PodType) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::vector<PodType, Allocator>::const_iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new modifiable buffer that represents the given string.
+/**
+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,
+ * data.size() * sizeof(Elem))</tt>.
+ *
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(Elem)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::basic_string<Elem, Traits, Allocator>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given string.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
+ *
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_MUTABLE_BUFFER buffer(
+    std::basic_string<Elem, Traits, Allocator>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_MUTABLE_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(Elem) < max_size_in_bytes
+      ? data.size() * sizeof(Elem) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::basic_string<Elem, Traits, Allocator>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given string.
+/**
+ * @returns <tt>const_buffer(data.data(), data.size() * sizeof(Elem))</tt>.
+ *
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(), data.size() * sizeof(Elem)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given string.
+/**
+ * @returns A const_buffer value equivalent to:
+ * @code const_buffer(
+ *     data.data(),
+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
+ *
+ * @note The buffer is invalidated by any non-const operation called on the
+ * given string object.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    const std::basic_string<Elem, Traits, Allocator>& data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.data(),
+      data.size() * sizeof(Elem) < max_size_in_bytes
+      ? data.size() * sizeof(Elem) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename std::basic_string<Elem, Traits, Allocator>::const_iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
+  || defined(GENERATING_DOCUMENTATION)
+
+/// Create a new modifiable buffer that represents the given string_view.
+/**
+ * @returns <tt>mutable_buffer(data.size() ? &data[0] : 0,
+ * data.size() * sizeof(Elem))</tt>.
+ */
+template <typename Elem, typename Traits>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    basic_string_view<Elem, Traits> data) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(Elem)
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename basic_string_view<Elem, Traits>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+/// Create a new non-modifiable buffer that represents the given string.
+/**
+ * @returns A mutable_buffer value equivalent to:
+ * @code mutable_buffer(
+ *     data.size() ? &data[0] : 0,
+ *     min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
+ */
+template <typename Elem, typename Traits>
+inline BOOST_ASIO_CONST_BUFFER buffer(
+    basic_string_view<Elem, Traits> data,
+    std::size_t max_size_in_bytes) BOOST_ASIO_NOEXCEPT
+{
+  return BOOST_ASIO_CONST_BUFFER(data.size() ? &data[0] : 0,
+      data.size() * sizeof(Elem) < max_size_in_bytes
+      ? data.size() * sizeof(Elem) : max_size_in_bytes
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+      , detail::buffer_debug_check<
+          typename basic_string_view<Elem, Traits>::iterator
+        >(data.begin())
+#endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
+      );
+}
+
+#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
+       //  || defined(GENERATING_DOCUMENTATION)
+
+/*@}*/
+
+/// Adapt a basic_string to the DynamicBuffer requirements.
+/**
+ * Requires that <tt>sizeof(Elem) == 1</tt>.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+class dynamic_string_buffer
+{
+public:
+  /// The type used to represent the input sequence as a list of buffers.
+  typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+
+  /// The type used to represent the output sequence as a list of buffers.
+  typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
+
+  /// Construct a dynamic buffer from a string.
+  /**
+   * @param s The string to be used as backing storage for the dynamic buffer.
+   * Any existing data in the string is treated as the dynamic buffer's input
+   * sequence. The object stores a reference to the string and the user is
+   * responsible for ensuring that the string object remains valid until the
+   * dynamic_string_buffer object is destroyed.
+   *
+   * @param maximum_size Specifies a maximum size for the buffer, in bytes.
+   */
+  explicit dynamic_string_buffer(std::basic_string<Elem, Traits, Allocator>& s,
+      std::size_t maximum_size =
+        (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+    : string_(s),
+      size_(string_.size()),
+      max_size_(maximum_size)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move construct a dynamic buffer.
+  dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT
+    : string_(other.string_),
+      size_(other.size_),
+      max_size_(other.max_size_)
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Get the size of the input sequence.
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return size_;
+  }
+
+  /// Get the maximum size of the dynamic buffer.
+  /**
+   * @returns The allowed maximum of the sum of the sizes of the input sequence
+   * and output sequence.
+   */
+  std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+  {
+    return max_size_;
+  }
+
+  /// Get the current capacity of the dynamic buffer.
+  /**
+   * @returns The current total capacity of the buffer, i.e. for both the input
+   * sequence and output sequence.
+   */
+  std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+  {
+    return string_.capacity();
+  }
+
+  /// Get a list of buffers that represents the input sequence.
+  /**
+   * @returns An object of type @c const_buffers_type that satisfies
+   * ConstBufferSequence requirements, representing the basic_string memory in
+   * input sequence.
+   *
+   * @note The returned object is invalidated by any @c dynamic_string_buffer
+   * or @c basic_string member function that modifies the input sequence or
+   * output sequence.
+   */
+  const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+  {
+    return const_buffers_type(boost::asio::buffer(string_, size_));
+  }
+
+  /// Get a list of buffers that represents the output sequence, with the given
+  /// size.
+  /**
+   * Ensures that the output sequence can accommodate @c n bytes, resizing the
+   * basic_string object as necessary.
+   *
+   * @returns An object of type @c mutable_buffers_type that satisfies
+   * MutableBufferSequence requirements, representing basic_string memory
+   * at the start of the output sequence of size @c n.
+   *
+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+   *
+   * @note The returned object is invalidated by any @c dynamic_string_buffer
+   * or @c basic_string member function that modifies the input sequence or
+   * output sequence.
+   */
+  mutable_buffers_type prepare(std::size_t n)
+  {
+    if (size () > max_size() || max_size() - size() < n)
+    {
+      std::length_error ex("dynamic_string_buffer too long");
+      boost::asio::detail::throw_exception(ex);
+    }
+
+    string_.resize(size_ + n);
+
+    return boost::asio::buffer(boost::asio::buffer(string_) + size_, n);
+  }
+
+  /// Move bytes from the output sequence to the input sequence.
+  /**
+   * @param n The number of bytes to append from the start of the output
+   * sequence to the end of the input sequence. The remainder of the output
+   * sequence is discarded.
+   *
+   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
+   * no intervening operations that modify the input or output sequence.
+   *
+   * @note If @c n is greater than the size of the output sequence, the entire
+   * output sequence is moved to the input sequence and no error is issued.
+   */
+  void commit(std::size_t n)
+  {
+    size_ += (std::min)(n, string_.size() - size_);
+    string_.resize(size_);
+  }
+
+  /// Remove characters from the input sequence.
+  /**
+   * Removes @c n characters from the beginning of the input sequence.
+   *
+   * @note If @c n is greater than the size of the input sequence, the entire
+   * input sequence is consumed and no error is issued.
+   */
+  void consume(std::size_t n)
+  {
+    std::size_t consume_length = (std::min)(n, size_);
+    string_.erase(0, consume_length);
+    size_ -= consume_length;
+  }
+
+private:
+  std::basic_string<Elem, Traits, Allocator>& string_;
+  std::size_t size_;
+  const std::size_t max_size_;
+};
+
+/// Adapt a vector to the DynamicBuffer requirements.
+/**
+ * Requires that <tt>sizeof(Elem) == 1</tt>.
+ */
+template <typename Elem, typename Allocator>
+class dynamic_vector_buffer
+{
+public:
+  /// The type used to represent the input sequence as a list of buffers.
+  typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
+
+  /// The type used to represent the output sequence as a list of buffers.
+  typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
+
+  /// Construct a dynamic buffer from a string.
+  /**
+   * @param v The vector to be used as backing storage for the dynamic buffer.
+   * Any existing data in the vector is treated as the dynamic buffer's input
+   * sequence. The object stores a reference to the vector and the user is
+   * responsible for ensuring that the vector object remains valid until the
+   * dynamic_vector_buffer object is destroyed.
+   *
+   * @param maximum_size Specifies a maximum size for the buffer, in bytes.
+   */
+  explicit dynamic_vector_buffer(std::vector<Elem, Allocator>& v,
+      std::size_t maximum_size =
+        (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+    : vector_(v),
+      size_(vector_.size()),
+      max_size_(maximum_size)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move construct a dynamic buffer.
+  dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT
+    : vector_(other.vector_),
+      size_(other.size_),
+      max_size_(other.max_size_)
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Get the size of the input sequence.
+  std::size_t size() const BOOST_ASIO_NOEXCEPT
+  {
+    return size_;
+  }
+
+  /// Get the maximum size of the dynamic buffer.
+  /**
+   * @returns The allowed maximum of the sum of the sizes of the input sequence
+   * and output sequence.
+   */
+  std::size_t max_size() const BOOST_ASIO_NOEXCEPT
+  {
+    return max_size_;
+  }
+
+  /// Get the current capacity of the dynamic buffer.
+  /**
+   * @returns The current total capacity of the buffer, i.e. for both the input
+   * sequence and output sequence.
+   */
+  std::size_t capacity() const BOOST_ASIO_NOEXCEPT
+  {
+    return vector_.capacity();
+  }
+
+  /// Get a list of buffers that represents the input sequence.
+  /**
+   * @returns An object of type @c const_buffers_type that satisfies
+   * ConstBufferSequence requirements, representing the basic_string memory in
+   * input sequence.
+   *
+   * @note The returned object is invalidated by any @c dynamic_vector_buffer
+   * or @c basic_string member function that modifies the input sequence or
+   * output sequence.
+   */
+  const_buffers_type data() const BOOST_ASIO_NOEXCEPT
+  {
+    return const_buffers_type(boost::asio::buffer(vector_, size_));
+  }
+
+  /// Get a list of buffers that represents the output sequence, with the given
+  /// size.
+  /**
+   * Ensures that the output sequence can accommodate @c n bytes, resizing the
+   * basic_string object as necessary.
+   *
+   * @returns An object of type @c mutable_buffers_type that satisfies
+   * MutableBufferSequence requirements, representing basic_string memory
+   * at the start of the output sequence of size @c n.
+   *
+   * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+   *
+   * @note The returned object is invalidated by any @c dynamic_vector_buffer
+   * or @c basic_string member function that modifies the input sequence or
+   * output sequence.
+   */
+  mutable_buffers_type prepare(std::size_t n)
+  {
+    if (size () > max_size() || max_size() - size() < n)
+    {
+      std::length_error ex("dynamic_vector_buffer too long");
+      boost::asio::detail::throw_exception(ex);
+    }
+
+    vector_.resize(size_ + n);
+
+    return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n);
+  }
+
+  /// Move bytes from the output sequence to the input sequence.
+  /**
+   * @param n The number of bytes to append from the start of the output
+   * sequence to the end of the input sequence. The remainder of the output
+   * sequence is discarded.
+   *
+   * Requires a preceding call <tt>prepare(x)</tt> where <tt>x >= n</tt>, and
+   * no intervening operations that modify the input or output sequence.
+   *
+   * @note If @c n is greater than the size of the output sequence, the entire
+   * output sequence is moved to the input sequence and no error is issued.
+   */
+  void commit(std::size_t n)
+  {
+    size_ += (std::min)(n, vector_.size() - size_);
+    vector_.resize(size_);
+  }
+
+  /// Remove characters from the input sequence.
+  /**
+   * Removes @c n characters from the beginning of the input sequence.
+   *
+   * @note If @c n is greater than the size of the input sequence, the entire
+   * input sequence is consumed and no error is issued.
+   */
+  void consume(std::size_t n)
+  {
+    std::size_t consume_length = (std::min)(n, size_);
+    vector_.erase(vector_.begin(), vector_.begin() + consume_length);
+    size_ -= consume_length;
+  }
+
+private:
+  std::vector<Elem, Allocator>& vector_;
+  std::size_t size_;
+  const std::size_t max_size_;
+};
+
+/** @defgroup dynamic_buffer boost::asio::dynamic_buffer
+ *
+ * @brief The boost::asio::dynamic_buffer function is used to create a
+ * dynamically resized buffer from a @c std::basic_string or @c std::vector.
+ */
+/*@{*/
+
+/// Create a new dynamic buffer that represents the given string.
+/**
+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data)</tt>.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
+    std::basic_string<Elem, Traits, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return dynamic_string_buffer<Elem, Traits, Allocator>(data);
+}
+
+/// Create a new dynamic buffer that represents the given string.
+/**
+ * @returns <tt>dynamic_string_buffer<Elem, Traits, Allocator>(data,
+ * max_size)</tt>.
+ */
+template <typename Elem, typename Traits, typename Allocator>
+inline dynamic_string_buffer<Elem, Traits, Allocator> dynamic_buffer(
+    std::basic_string<Elem, Traits, Allocator>& data,
+    std::size_t max_size) BOOST_ASIO_NOEXCEPT
+{
+  return dynamic_string_buffer<Elem, Traits, Allocator>(data, max_size);
+}
+
+/// Create a new dynamic buffer that represents the given vector.
+/**
+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data)</tt>.
+ */
+template <typename Elem, typename Allocator>
+inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
+    std::vector<Elem, Allocator>& data) BOOST_ASIO_NOEXCEPT
+{
+  return dynamic_vector_buffer<Elem, Allocator>(data);
+}
+
+/// Create a new dynamic buffer that represents the given vector.
+/**
+ * @returns <tt>dynamic_vector_buffer<Elem, Allocator>(data, max_size)</tt>.
+ */
+template <typename Elem, typename Allocator>
+inline dynamic_vector_buffer<Elem, Allocator> dynamic_buffer(
+    std::vector<Elem, Allocator>& data,
+    std::size_t max_size) BOOST_ASIO_NOEXCEPT
+{
+  return dynamic_vector_buffer<Elem, Allocator>(data, max_size);
+}
+
+/*@}*/
+
+/** @defgroup buffer_copy boost::asio::buffer_copy
+ *
+ * @brief The boost::asio::buffer_copy function is used to copy bytes from a
+ * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
+ *
+ * The @c buffer_copy function is available in two forms:
+ *
+ * @li A 2-argument form: @c buffer_copy(target, source)
+ *
+ * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)
+ *
+ * Both forms return the number of bytes actually copied. The number of bytes
+ * copied is the lesser of:
+ *
+ * @li @c buffer_size(target)
+ *
+ * @li @c buffer_size(source)
+ *
+ * @li @c If specified, @c max_bytes_to_copy.
+ *
+ * This prevents buffer overflow, regardless of the buffer sizes used in the
+ * copy operation.
+ *
+ * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
+ * consequently it cannot be used to copy between overlapping memory regions.
+ */
+/*@{*/
+
+namespace detail {
+
+inline std::size_t buffer_copy_1(const mutable_buffer& target,
+    const const_buffer& source)
+{
+  using namespace std; // For memcpy.
+  std::size_t target_size = target.size();
+  std::size_t source_size = source.size();
+  std::size_t n = target_size < source_size ? target_size : source_size;
+  if (n > 0)
+    memcpy(target.data(), source.data(), n);
+  return n;
+}
+
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator) BOOST_ASIO_NOEXCEPT
+{
+  return (buffer_copy_1)(*target_begin, *source_begin);
+}
+
+template <typename TargetIterator, typename SourceIterator>
+inline std::size_t buffer_copy(one_buffer, one_buffer,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator,
+    std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
+{
+  return (buffer_copy_1)(*target_begin,
+      boost::asio::buffer(*source_begin, max_bytes_to_copy));
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(one_buffer, multiple_buffers,
+    TargetIterator target_begin, TargetIterator,
+    SourceIterator source_begin, SourceIterator source_end,
+    std::size_t max_bytes_to_copy
+      = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t total_bytes_copied = 0;
+  SourceIterator source_iter = source_begin;
+
+  for (mutable_buffer target_buffer(
+        boost::asio::buffer(*target_begin, max_bytes_to_copy));
+      target_buffer.size() && source_iter != source_end; ++source_iter)
+  {
+    const_buffer source_buffer(*source_iter);
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
+    total_bytes_copied += bytes_copied;
+    target_buffer += bytes_copied;
+  }
+
+  return total_bytes_copied;
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, one_buffer,
+    TargetIterator target_begin, TargetIterator target_end,
+    SourceIterator source_begin, SourceIterator,
+    std::size_t max_bytes_to_copy
+      = (std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t total_bytes_copied = 0;
+  TargetIterator target_iter = target_begin;
+
+  for (const_buffer source_buffer(
+        boost::asio::buffer(*source_begin, max_bytes_to_copy));
+      source_buffer.size() && target_iter != target_end; ++target_iter)
+  {
+    mutable_buffer target_buffer(*target_iter);
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
+    total_bytes_copied += bytes_copied;
+    source_buffer += bytes_copied;
+  }
+
+  return total_bytes_copied;
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
+    TargetIterator target_begin, TargetIterator target_end,
+    SourceIterator source_begin, SourceIterator source_end) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t total_bytes_copied = 0;
+
+  TargetIterator target_iter = target_begin;
+  std::size_t target_buffer_offset = 0;
+
+  SourceIterator source_iter = source_begin;
+  std::size_t source_buffer_offset = 0;
+
+  while (target_iter != target_end && source_iter != source_end)
+  {
+    mutable_buffer target_buffer =
+      mutable_buffer(*target_iter) + target_buffer_offset;
+
+    const_buffer source_buffer =
+      const_buffer(*source_iter) + source_buffer_offset;
+
+    std::size_t bytes_copied = (buffer_copy_1)(target_buffer, source_buffer);
+    total_bytes_copied += bytes_copied;
+
+    if (bytes_copied == target_buffer.size())
+    {
+      ++target_iter;
+      target_buffer_offset = 0;
+    }
+    else
+      target_buffer_offset += bytes_copied;
+
+    if (bytes_copied == source_buffer.size())
+    {
+      ++source_iter;
+      source_buffer_offset = 0;
+    }
+    else
+      source_buffer_offset += bytes_copied;
+  }
+
+  return total_bytes_copied;
+}
+
+template <typename TargetIterator, typename SourceIterator>
+std::size_t buffer_copy(multiple_buffers, multiple_buffers,
+    TargetIterator target_begin, TargetIterator target_end,
+    SourceIterator source_begin, SourceIterator source_end,
+    std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
+{
+  std::size_t total_bytes_copied = 0;
+
+  TargetIterator target_iter = target_begin;
+  std::size_t target_buffer_offset = 0;
+
+  SourceIterator source_iter = source_begin;
+  std::size_t source_buffer_offset = 0;
+
+  while (total_bytes_copied != max_bytes_to_copy
+      && target_iter != target_end && source_iter != source_end)
+  {
+    mutable_buffer target_buffer =
+      mutable_buffer(*target_iter) + target_buffer_offset;
+
+    const_buffer source_buffer =
+      const_buffer(*source_iter) + source_buffer_offset;
+
+    std::size_t bytes_copied = (buffer_copy_1)(
+        target_buffer, boost::asio::buffer(source_buffer,
+          max_bytes_to_copy - total_bytes_copied));
+    total_bytes_copied += bytes_copied;
+
+    if (bytes_copied == target_buffer.size())
+    {
+      ++target_iter;
+      target_buffer_offset = 0;
+    }
+    else
+      target_buffer_offset += bytes_copied;
+
+    if (bytes_copied == source_buffer.size())
+    {
+      ++source_iter;
+      source_buffer_offset = 0;
+    }
+    else
+      source_buffer_offset += bytes_copied;
+  }
+
+  return total_bytes_copied;
+}
+
+} // namespace detail
+
+/// Copies bytes from a source buffer sequence to a target buffer sequence.
+/**
+ * @param target A modifiable buffer sequence representing the memory regions to
+ * which the bytes will be copied.
+ *
+ * @param source A non-modifiable buffer sequence representing the memory
+ * regions from which the bytes will be copied.
+ *
+ * @returns The number of bytes copied.
+ *
+ * @note The number of bytes copied is the lesser of:
+ *
+ * @li @c buffer_size(target)
+ *
+ * @li @c buffer_size(source)
+ *
+ * This function is implemented in terms of @c memcpy, and consequently it
+ * cannot be used to copy between overlapping memory regions.
+ */
+template <typename MutableBufferSequence, typename ConstBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+    const ConstBufferSequence& source) BOOST_ASIO_NOEXCEPT
+{
+  return detail::buffer_copy(
+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),
+      boost::asio::buffer_sequence_begin(target),
+      boost::asio::buffer_sequence_end(target),
+      boost::asio::buffer_sequence_begin(source),
+      boost::asio::buffer_sequence_end(source));
+}
+
+/// Copies a limited number of bytes from a source buffer sequence to a target
+/// buffer sequence.
+/**
+ * @param target A modifiable buffer sequence representing the memory regions to
+ * which the bytes will be copied.
+ *
+ * @param source A non-modifiable buffer sequence representing the memory
+ * regions from which the bytes will be copied.
+ *
+ * @param max_bytes_to_copy The maximum number of bytes to be copied.
+ *
+ * @returns The number of bytes copied.
+ *
+ * @note The number of bytes copied is the lesser of:
+ *
+ * @li @c buffer_size(target)
+ *
+ * @li @c buffer_size(source)
+ *
+ * @li @c max_bytes_to_copy
+ *
+ * This function is implemented in terms of @c memcpy, and consequently it
+ * cannot be used to copy between overlapping memory regions.
+ */
+template <typename MutableBufferSequence, typename ConstBufferSequence>
+inline std::size_t buffer_copy(const MutableBufferSequence& target,
+    const ConstBufferSequence& source,
+    std::size_t max_bytes_to_copy) BOOST_ASIO_NOEXCEPT
+{
+  return detail::buffer_copy(
+      detail::buffer_sequence_cardinality<MutableBufferSequence>(),
+      detail::buffer_sequence_cardinality<ConstBufferSequence>(),
+      boost::asio::buffer_sequence_begin(target),
+      boost::asio::buffer_sequence_end(target),
+      boost::asio::buffer_sequence_begin(source),
+      boost::asio::buffer_sequence_end(source), max_bytes_to_copy);
+}
+
+/*@}*/
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BUFFER_HPP

+ 259 - 0
cpir-read/boost/boost/asio/buffered_read_stream.hpp

@@ -0,0 +1,259 @@
+//
+// buffered_read_stream.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_READ_STREAM_HPP
+#define BOOST_ASIO_BUFFERED_READ_STREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/buffered_read_stream_fwd.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_resize_guard.hpp>
+#include <boost/asio/detail/buffered_stream_storage.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Adds buffering to the read-related operations of a stream.
+/**
+ * The buffered_read_stream class template can be used to add buffering to the
+ * synchronous and asynchronous read operations of a stream.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
+ */
+template <typename Stream>
+class buffered_read_stream
+  : private noncopyable
+{
+public:
+  /// The type of the next layer.
+  typedef typename remove_reference<Stream>::type next_layer_type;
+
+  /// The type of the lowest layer.
+  typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+
+  /// The type of the executor associated with the object.
+  typedef typename lowest_layer_type::executor_type executor_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// The default buffer size.
+  static const std::size_t default_buffer_size = implementation_defined;
+#else
+  BOOST_ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
+#endif
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  explicit buffered_read_stream(Arg& a)
+    : next_layer_(a),
+      storage_(default_buffer_size)
+  {
+  }
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  buffered_read_stream(Arg& a, std::size_t buffer_size)
+    : next_layer_(a),
+      storage_(buffer_size)
+  {
+  }
+
+  /// Get a reference to the next layer.
+  next_layer_type& next_layer()
+  {
+    return next_layer_;
+  }
+
+  /// Get a reference to the lowest layer.
+  lowest_layer_type& lowest_layer()
+  {
+    return next_layer_.lowest_layer();
+  }
+
+  /// Get a const reference to the lowest layer.
+  const lowest_layer_type& lowest_layer() const
+  {
+    return next_layer_.lowest_layer();
+  }
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return next_layer_.lowest_layer().get_executor();
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_context()
+  {
+    return next_layer_.get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_service()
+  {
+    return next_layer_.get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Close the stream.
+  void close()
+  {
+    next_layer_.close();
+  }
+
+  /// Close the stream.
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    next_layer_.close(ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Write the given data to the stream. Returns the number of bytes written.
+  /// Throws an exception on failure.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers)
+  {
+    return next_layer_.write_some(buffers);
+  }
+
+  /// Write the given data to the stream. Returns the number of bytes written,
+  /// or 0 if an error occurred.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return next_layer_.write_some(buffers, ec);
+  }
+
+  /// Start an asynchronous write. The data being written must be valid for the
+  /// lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_write_some(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    return next_layer_.async_write_some(buffers,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+  }
+
+  /// Fill the buffer with some data. Returns the number of bytes placed in the
+  /// buffer as a result of the operation. Throws an exception on failure.
+  std::size_t fill();
+
+  /// Fill the buffer with some data. Returns the number of bytes placed in the
+  /// buffer as a result of the operation, or 0 if an error occurred.
+  std::size_t fill(boost::system::error_code& ec);
+
+  /// Start an asynchronous fill.
+  template <typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_fill(BOOST_ASIO_MOVE_ARG(ReadHandler) handler);
+
+  /// Read some data from the stream. Returns the number of bytes read. Throws
+  /// an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers);
+
+  /// Read some data from the stream. Returns the number of bytes read or 0 if
+  /// an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec);
+
+  /// Start an asynchronous read. The buffer into which the data will be read
+  /// must be valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_read_some(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler);
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read.
+  /// Throws an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers);
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read,
+  /// or 0 if an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec);
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail()
+  {
+    return storage_.size();
+  }
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail(boost::system::error_code& ec)
+  {
+    ec = boost::system::error_code();
+    return storage_.size();
+  }
+
+private:
+  /// Copy data out of the internal buffer to the specified target buffer.
+  /// Returns the number of bytes copied.
+  template <typename MutableBufferSequence>
+  std::size_t copy(const MutableBufferSequence& buffers)
+  {
+    std::size_t bytes_copied = boost::asio::buffer_copy(
+        buffers, storage_.data(), storage_.size());
+    storage_.consume(bytes_copied);
+    return bytes_copied;
+  }
+
+  /// Copy data from the internal buffer to the specified target buffer, without
+  /// removing the data from the internal buffer. Returns the number of bytes
+  /// copied.
+  template <typename MutableBufferSequence>
+  std::size_t peek_copy(const MutableBufferSequence& buffers)
+  {
+    return boost::asio::buffer_copy(buffers, storage_.data(), storage_.size());
+  }
+
+  /// The next layer.
+  Stream next_layer_;
+
+  // The data in the buffer.
+  detail::buffered_stream_storage storage_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/buffered_read_stream.hpp>
+
+#endif // BOOST_ASIO_BUFFERED_READ_STREAM_HPP

+ 27 - 0
cpir-read/boost/boost/asio/buffered_read_stream_fwd.hpp

@@ -0,0 +1,27 @@
+//
+// buffered_read_stream_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP
+#define BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+namespace boost {
+namespace asio {
+
+template <typename Stream>
+class buffered_read_stream;
+
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP

+ 280 - 0
cpir-read/boost/boost/asio/buffered_stream.hpp

@@ -0,0 +1,280 @@
+//
+// buffered_stream.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_STREAM_HPP
+#define BOOST_ASIO_BUFFERED_STREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/buffered_read_stream.hpp>
+#include <boost/asio/buffered_write_stream.hpp>
+#include <boost/asio/buffered_stream_fwd.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Adds buffering to the read- and write-related operations of a stream.
+/**
+ * The buffered_stream class template can be used to add buffering to the
+ * synchronous and asynchronous read and write operations of a stream.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
+ */
+template <typename Stream>
+class buffered_stream
+  : private noncopyable
+{
+public:
+  /// The type of the next layer.
+  typedef typename remove_reference<Stream>::type next_layer_type;
+
+  /// The type of the lowest layer.
+  typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+
+  /// The type of the executor associated with the object.
+  typedef typename lowest_layer_type::executor_type executor_type;
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  explicit buffered_stream(Arg& a)
+    : inner_stream_impl_(a),
+      stream_impl_(inner_stream_impl_)
+  {
+  }
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  explicit buffered_stream(Arg& a, std::size_t read_buffer_size,
+      std::size_t write_buffer_size)
+    : inner_stream_impl_(a, write_buffer_size),
+      stream_impl_(inner_stream_impl_, read_buffer_size)
+  {
+  }
+
+  /// Get a reference to the next layer.
+  next_layer_type& next_layer()
+  {
+    return stream_impl_.next_layer().next_layer();
+  }
+
+  /// Get a reference to the lowest layer.
+  lowest_layer_type& lowest_layer()
+  {
+    return stream_impl_.lowest_layer();
+  }
+
+  /// Get a const reference to the lowest layer.
+  const lowest_layer_type& lowest_layer() const
+  {
+    return stream_impl_.lowest_layer();
+  }
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return stream_impl_.lowest_layer().get_executor();
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_context()
+  {
+    return stream_impl_.get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_service()
+  {
+    return stream_impl_.get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Close the stream.
+  void close()
+  {
+    stream_impl_.close();
+  }
+
+  /// Close the stream.
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    stream_impl_.close(ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Flush all data from the buffer to the next layer. Returns the number of
+  /// bytes written to the next layer on the last write operation. Throws an
+  /// exception on failure.
+  std::size_t flush()
+  {
+    return stream_impl_.next_layer().flush();
+  }
+
+  /// Flush all data from the buffer to the next layer. Returns the number of
+  /// bytes written to the next layer on the last write operation, or 0 if an
+  /// error occurred.
+  std::size_t flush(boost::system::error_code& ec)
+  {
+    return stream_impl_.next_layer().flush(ec);
+  }
+
+  /// Start an asynchronous flush.
+  template <typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_flush(BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    return stream_impl_.next_layer().async_flush(
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+  }
+
+  /// Write the given data to the stream. Returns the number of bytes written.
+  /// Throws an exception on failure.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers)
+  {
+    return stream_impl_.write_some(buffers);
+  }
+
+  /// Write the given data to the stream. Returns the number of bytes written,
+  /// or 0 if an error occurred.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return stream_impl_.write_some(buffers, ec);
+  }
+
+  /// Start an asynchronous write. The data being written must be valid for the
+  /// lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_write_some(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    return stream_impl_.async_write_some(buffers,
+        BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+  }
+
+  /// Fill the buffer with some data. Returns the number of bytes placed in the
+  /// buffer as a result of the operation. Throws an exception on failure.
+  std::size_t fill()
+  {
+    return stream_impl_.fill();
+  }
+
+  /// Fill the buffer with some data. Returns the number of bytes placed in the
+  /// buffer as a result of the operation, or 0 if an error occurred.
+  std::size_t fill(boost::system::error_code& ec)
+  {
+    return stream_impl_.fill(ec);
+  }
+
+  /// Start an asynchronous fill.
+  template <typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_fill(BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    return stream_impl_.async_fill(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+  }
+
+  /// Read some data from the stream. Returns the number of bytes read. Throws
+  /// an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers)
+  {
+    return stream_impl_.read_some(buffers);
+  }
+
+  /// Read some data from the stream. Returns the number of bytes read or 0 if
+  /// an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return stream_impl_.read_some(buffers, ec);
+  }
+
+  /// Start an asynchronous read. The buffer into which the data will be read
+  /// must be valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_read_some(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    return stream_impl_.async_read_some(buffers,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+  }
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read.
+  /// Throws an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers)
+  {
+    return stream_impl_.peek(buffers);
+  }
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read,
+  /// or 0 if an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return stream_impl_.peek(buffers, ec);
+  }
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail()
+  {
+    return stream_impl_.in_avail();
+  }
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail(boost::system::error_code& ec)
+  {
+    return stream_impl_.in_avail(ec);
+  }
+
+private:
+  // The buffered write stream.
+  typedef buffered_write_stream<Stream> write_stream_type;
+  write_stream_type inner_stream_impl_;
+
+  // The buffered read stream.
+  typedef buffered_read_stream<write_stream_type&> read_stream_type;
+  read_stream_type stream_impl_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BUFFERED_STREAM_HPP

+ 27 - 0
cpir-read/boost/boost/asio/buffered_stream_fwd.hpp

@@ -0,0 +1,27 @@
+//
+// buffered_stream_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_STREAM_FWD_HPP
+#define BOOST_ASIO_BUFFERED_STREAM_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+namespace boost {
+namespace asio {
+
+template <typename Stream>
+class buffered_stream;
+
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_BUFFERED_STREAM_FWD_HPP

+ 251 - 0
cpir-read/boost/boost/asio/buffered_write_stream.hpp

@@ -0,0 +1,251 @@
+//
+// buffered_write_stream.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP
+#define BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/buffered_write_stream_fwd.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/completion_condition.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffered_stream_storage.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/write.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Adds buffering to the write-related operations of a stream.
+/**
+ * The buffered_write_stream class template can be used to add buffering to the
+ * synchronous and asynchronous write operations of a stream.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
+ */
+template <typename Stream>
+class buffered_write_stream
+  : private noncopyable
+{
+public:
+  /// The type of the next layer.
+  typedef typename remove_reference<Stream>::type next_layer_type;
+
+  /// The type of the lowest layer.
+  typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+
+  /// The type of the executor associated with the object.
+  typedef typename lowest_layer_type::executor_type executor_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// The default buffer size.
+  static const std::size_t default_buffer_size = implementation_defined;
+#else
+  BOOST_ASIO_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
+#endif
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  explicit buffered_write_stream(Arg& a)
+    : next_layer_(a),
+      storage_(default_buffer_size)
+  {
+  }
+
+  /// Construct, passing the specified argument to initialise the next layer.
+  template <typename Arg>
+  buffered_write_stream(Arg& a, std::size_t buffer_size)
+    : next_layer_(a),
+      storage_(buffer_size)
+  {
+  }
+
+  /// Get a reference to the next layer.
+  next_layer_type& next_layer()
+  {
+    return next_layer_;
+  }
+
+  /// Get a reference to the lowest layer.
+  lowest_layer_type& lowest_layer()
+  {
+    return next_layer_.lowest_layer();
+  }
+
+  /// Get a const reference to the lowest layer.
+  const lowest_layer_type& lowest_layer() const
+  {
+    return next_layer_.lowest_layer();
+  }
+
+  /// Get the executor associated with the object.
+  executor_type get_executor() BOOST_ASIO_NOEXCEPT
+  {
+    return next_layer_.lowest_layer().get_executor();
+  }
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_context()
+  {
+    return next_layer_.get_io_context();
+  }
+
+  /// (Deprecated: Use get_executor().) Get the io_context associated with the
+  /// object.
+  boost::asio::io_context& get_io_service()
+  {
+    return next_layer_.get_io_service();
+  }
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  /// Close the stream.
+  void close()
+  {
+    next_layer_.close();
+  }
+
+  /// Close the stream.
+  BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+  {
+    next_layer_.close(ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Flush all data from the buffer to the next layer. Returns the number of
+  /// bytes written to the next layer on the last write operation. Throws an
+  /// exception on failure.
+  std::size_t flush();
+
+  /// Flush all data from the buffer to the next layer. Returns the number of
+  /// bytes written to the next layer on the last write operation, or 0 if an
+  /// error occurred.
+  std::size_t flush(boost::system::error_code& ec);
+
+  /// Start an asynchronous flush.
+  template <typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_flush(BOOST_ASIO_MOVE_ARG(WriteHandler) handler);
+
+  /// Write the given data to the stream. Returns the number of bytes written.
+  /// Throws an exception on failure.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers);
+
+  /// Write the given data to the stream. Returns the number of bytes written,
+  /// or 0 if an error occurred and the error handler did not throw.
+  template <typename ConstBufferSequence>
+  std::size_t write_some(const ConstBufferSequence& buffers,
+      boost::system::error_code& ec);
+
+  /// Start an asynchronous write. The data being written must be valid for the
+  /// lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_write_some(const ConstBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler);
+
+  /// Read some data from the stream. Returns the number of bytes read. Throws
+  /// an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers)
+  {
+    return next_layer_.read_some(buffers);
+  }
+
+  /// Read some data from the stream. Returns the number of bytes read or 0 if
+  /// an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t read_some(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return next_layer_.read_some(buffers, ec);
+  }
+
+  /// Start an asynchronous read. The buffer into which the data will be read
+  /// must be valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_read_some(const MutableBufferSequence& buffers,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    return next_layer_.async_read_some(buffers,
+        BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+  }
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read.
+  /// Throws an exception on failure.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers)
+  {
+    return next_layer_.peek(buffers);
+  }
+
+  /// Peek at the incoming data on the stream. Returns the number of bytes read,
+  /// or 0 if an error occurred.
+  template <typename MutableBufferSequence>
+  std::size_t peek(const MutableBufferSequence& buffers,
+      boost::system::error_code& ec)
+  {
+    return next_layer_.peek(buffers, ec);
+  }
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail()
+  {
+    return next_layer_.in_avail();
+  }
+
+  /// Determine the amount of data that may be read without blocking.
+  std::size_t in_avail(boost::system::error_code& ec)
+  {
+    return next_layer_.in_avail(ec);
+  }
+
+private:
+  /// Copy data into the internal buffer from the specified source buffer.
+  /// Returns the number of bytes copied.
+  template <typename ConstBufferSequence>
+  std::size_t copy(const ConstBufferSequence& buffers);
+
+  /// The next layer.
+  Stream next_layer_;
+
+  // The data in the buffer.
+  detail::buffered_stream_storage storage_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/buffered_write_stream.hpp>
+
+#endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_HPP

+ 27 - 0
cpir-read/boost/boost/asio/buffered_write_stream_fwd.hpp

@@ -0,0 +1,27 @@
+//
+// buffered_write_stream_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP
+#define BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+namespace boost {
+namespace asio {
+
+template <typename Stream>
+class buffered_write_stream;
+
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP

+ 523 - 0
cpir-read/boost/boost/asio/buffers_iterator.hpp

@@ -0,0 +1,523 @@
+//
+// buffers_iterator.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERS_ITERATOR_HPP
+#define BOOST_ASIO_BUFFERS_ITERATOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <iterator>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/assert.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+namespace detail
+{
+  template <bool IsMutable>
+  struct buffers_iterator_types_helper;
+
+  template <>
+  struct buffers_iterator_types_helper<false>
+  {
+    typedef const_buffer buffer_type;
+    template <typename ByteType>
+    struct byte_type
+    {
+      typedef typename add_const<ByteType>::type type;
+    };
+  };
+
+  template <>
+  struct buffers_iterator_types_helper<true>
+  {
+    typedef mutable_buffer buffer_type;
+    template <typename ByteType>
+    struct byte_type
+    {
+      typedef ByteType type;
+    };
+  };
+
+  template <typename BufferSequence, typename ByteType>
+  struct buffers_iterator_types
+  {
+    enum
+    {
+      is_mutable = is_convertible<
+          typename BufferSequence::value_type,
+          mutable_buffer>::value
+    };
+    typedef buffers_iterator_types_helper<is_mutable> helper;
+    typedef typename helper::buffer_type buffer_type;
+    typedef typename helper::template byte_type<ByteType>::type byte_type;
+    typedef typename BufferSequence::const_iterator const_iterator;
+  };
+
+  template <typename ByteType>
+  struct buffers_iterator_types<mutable_buffer, ByteType>
+  {
+    typedef mutable_buffer buffer_type;
+    typedef ByteType byte_type;
+    typedef const mutable_buffer* const_iterator;
+  };
+
+  template <typename ByteType>
+  struct buffers_iterator_types<const_buffer, ByteType>
+  {
+    typedef const_buffer buffer_type;
+    typedef typename add_const<ByteType>::type byte_type;
+    typedef const const_buffer* const_iterator;
+  };
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+  template <typename ByteType>
+  struct buffers_iterator_types<mutable_buffers_1, ByteType>
+  {
+    typedef mutable_buffer buffer_type;
+    typedef ByteType byte_type;
+    typedef const mutable_buffer* const_iterator;
+  };
+
+  template <typename ByteType>
+  struct buffers_iterator_types<const_buffers_1, ByteType>
+  {
+    typedef const_buffer buffer_type;
+    typedef typename add_const<ByteType>::type byte_type;
+    typedef const const_buffer* const_iterator;
+  };
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+}
+
+/// A random access iterator over the bytes in a buffer sequence.
+template <typename BufferSequence, typename ByteType = char>
+class buffers_iterator
+{
+private:
+  typedef typename detail::buffers_iterator_types<
+      BufferSequence, ByteType>::buffer_type buffer_type;
+
+  typedef typename detail::buffers_iterator_types<BufferSequence,
+          ByteType>::const_iterator buffer_sequence_iterator_type;
+
+public:
+  /// The type used for the distance between two iterators.
+  typedef std::ptrdiff_t difference_type;
+
+  /// The type of the value pointed to by the iterator.
+  typedef ByteType value_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// The type of the result of applying operator->() to the iterator.
+  /**
+   * If the buffer sequence stores buffer objects that are convertible to
+   * mutable_buffer, this is a pointer to a non-const ByteType. Otherwise, a
+   * pointer to a const ByteType.
+   */
+  typedef const_or_non_const_ByteType* pointer;
+#else // defined(GENERATING_DOCUMENTATION)
+  typedef typename detail::buffers_iterator_types<
+      BufferSequence, ByteType>::byte_type* pointer;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+#if defined(GENERATING_DOCUMENTATION)
+  /// The type of the result of applying operator*() to the iterator.
+  /**
+   * If the buffer sequence stores buffer objects that are convertible to
+   * mutable_buffer, this is a reference to a non-const ByteType. Otherwise, a
+   * reference to a const ByteType.
+   */
+  typedef const_or_non_const_ByteType& reference;
+#else // defined(GENERATING_DOCUMENTATION)
+  typedef typename detail::buffers_iterator_types<
+      BufferSequence, ByteType>::byte_type& reference;
+#endif // defined(GENERATING_DOCUMENTATION)
+
+  /// The iterator category.
+  typedef std::random_access_iterator_tag iterator_category;
+
+  /// Default constructor. Creates an iterator in an undefined state.
+  buffers_iterator()
+    : current_buffer_(),
+      current_buffer_position_(0),
+      begin_(),
+      current_(),
+      end_(),
+      position_(0)
+  {
+  }
+
+  /// Construct an iterator representing the beginning of the buffers' data.
+  static buffers_iterator begin(const BufferSequence& buffers)
+#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+    __attribute__ ((__noinline__))
+#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+  {
+    buffers_iterator new_iter;
+    new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
+    new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
+    new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
+    while (new_iter.current_ != new_iter.end_)
+    {
+      new_iter.current_buffer_ = *new_iter.current_;
+      if (new_iter.current_buffer_.size() > 0)
+        break;
+      ++new_iter.current_;
+    }
+    return new_iter;
+  }
+
+  /// Construct an iterator representing the end of the buffers' data.
+  static buffers_iterator end(const BufferSequence& buffers)
+#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+    __attribute__ ((__noinline__))
+#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+  {
+    buffers_iterator new_iter;
+    new_iter.begin_ = boost::asio::buffer_sequence_begin(buffers);
+    new_iter.current_ = boost::asio::buffer_sequence_begin(buffers);
+    new_iter.end_ = boost::asio::buffer_sequence_end(buffers);
+    while (new_iter.current_ != new_iter.end_)
+    {
+      buffer_type buffer = *new_iter.current_;
+      new_iter.position_ += buffer.size();
+      ++new_iter.current_;
+    }
+    return new_iter;
+  }
+
+  /// Dereference an iterator.
+  reference operator*() const
+  {
+    return dereference();
+  }
+
+  /// Dereference an iterator.
+  pointer operator->() const
+  {
+    return &dereference();
+  }
+
+  /// Access an individual element.
+  reference operator[](std::ptrdiff_t difference) const
+  {
+    buffers_iterator tmp(*this);
+    tmp.advance(difference);
+    return *tmp;
+  }
+
+  /// Increment operator (prefix).
+  buffers_iterator& operator++()
+  {
+    increment();
+    return *this;
+  }
+
+  /// Increment operator (postfix).
+  buffers_iterator operator++(int)
+  {
+    buffers_iterator tmp(*this);
+    ++*this;
+    return tmp;
+  }
+
+  /// Decrement operator (prefix).
+  buffers_iterator& operator--()
+  {
+    decrement();
+    return *this;
+  }
+
+  /// Decrement operator (postfix).
+  buffers_iterator operator--(int)
+  {
+    buffers_iterator tmp(*this);
+    --*this;
+    return tmp;
+  }
+
+  /// Addition operator.
+  buffers_iterator& operator+=(std::ptrdiff_t difference)
+  {
+    advance(difference);
+    return *this;
+  }
+
+  /// Subtraction operator.
+  buffers_iterator& operator-=(std::ptrdiff_t difference)
+  {
+    advance(-difference);
+    return *this;
+  }
+
+  /// Addition operator.
+  friend buffers_iterator operator+(const buffers_iterator& iter,
+      std::ptrdiff_t difference)
+  {
+    buffers_iterator tmp(iter);
+    tmp.advance(difference);
+    return tmp;
+  }
+
+  /// Addition operator.
+  friend buffers_iterator operator+(std::ptrdiff_t difference,
+      const buffers_iterator& iter)
+  {
+    buffers_iterator tmp(iter);
+    tmp.advance(difference);
+    return tmp;
+  }
+
+  /// Subtraction operator.
+  friend buffers_iterator operator-(const buffers_iterator& iter,
+      std::ptrdiff_t difference)
+  {
+    buffers_iterator tmp(iter);
+    tmp.advance(-difference);
+    return tmp;
+  }
+
+  /// Subtraction operator.
+  friend std::ptrdiff_t operator-(const buffers_iterator& a,
+      const buffers_iterator& b)
+  {
+    return b.distance_to(a);
+  }
+
+  /// Test two iterators for equality.
+  friend bool operator==(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return a.equal(b);
+  }
+
+  /// Test two iterators for inequality.
+  friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !a.equal(b);
+  }
+
+  /// Compare two iterators.
+  friend bool operator<(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return a.distance_to(b) > 0;
+  }
+
+  /// Compare two iterators.
+  friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !(b < a);
+  }
+
+  /// Compare two iterators.
+  friend bool operator>(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return b < a;
+  }
+
+  /// Compare two iterators.
+  friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !(a < b);
+  }
+
+private:
+  // Dereference the iterator.
+  reference dereference() const
+  {
+    return static_cast<pointer>(
+        current_buffer_.data())[current_buffer_position_];
+  }
+
+  // Compare two iterators for equality.
+  bool equal(const buffers_iterator& other) const
+  {
+    return position_ == other.position_;
+  }
+
+  // Increment the iterator.
+  void increment()
+  {
+    BOOST_ASIO_ASSERT(current_ != end_ && "iterator out of bounds");
+    ++position_;
+
+    // Check if the increment can be satisfied by the current buffer.
+    ++current_buffer_position_;
+    if (current_buffer_position_ != current_buffer_.size())
+      return;
+
+    // Find the next non-empty buffer.
+    ++current_;
+    current_buffer_position_ = 0;
+    while (current_ != end_)
+    {
+      current_buffer_ = *current_;
+      if (current_buffer_.size() > 0)
+        return;
+      ++current_;
+    }
+  }
+
+  // Decrement the iterator.
+  void decrement()
+  {
+    BOOST_ASIO_ASSERT(position_ > 0 && "iterator out of bounds");
+    --position_;
+
+    // Check if the decrement can be satisfied by the current buffer.
+    if (current_buffer_position_ != 0)
+    {
+      --current_buffer_position_;
+      return;
+    }
+
+    // Find the previous non-empty buffer.
+    buffer_sequence_iterator_type iter = current_;
+    while (iter != begin_)
+    {
+      --iter;
+      buffer_type buffer = *iter;
+      std::size_t buffer_size = buffer.size();
+      if (buffer_size > 0)
+      {
+        current_ = iter;
+        current_buffer_ = buffer;
+        current_buffer_position_ = buffer_size - 1;
+        return;
+      }
+    }
+  }
+
+  // Advance the iterator by the specified distance.
+  void advance(std::ptrdiff_t n)
+  {
+    if (n > 0)
+    {
+      BOOST_ASIO_ASSERT(current_ != end_ && "iterator out of bounds");
+      for (;;)
+      {
+        std::ptrdiff_t current_buffer_balance
+          = current_buffer_.size() - current_buffer_position_;
+
+        // Check if the advance can be satisfied by the current buffer.
+        if (current_buffer_balance > n)
+        {
+          position_ += n;
+          current_buffer_position_ += n;
+          return;
+        }
+
+        // Update position.
+        n -= current_buffer_balance;
+        position_ += current_buffer_balance;
+
+        // Move to next buffer. If it is empty then it will be skipped on the
+        // next iteration of this loop.
+        if (++current_ == end_)
+        {
+          BOOST_ASIO_ASSERT(n == 0 && "iterator out of bounds");
+          current_buffer_ = buffer_type();
+          current_buffer_position_ = 0;
+          return;
+        }
+        current_buffer_ = *current_;
+        current_buffer_position_ = 0;
+      }
+    }
+    else if (n < 0)
+    {
+      std::size_t abs_n = -n;
+      BOOST_ASIO_ASSERT(position_ >= abs_n && "iterator out of bounds");
+      for (;;)
+      {
+        // Check if the advance can be satisfied by the current buffer.
+        if (current_buffer_position_ >= abs_n)
+        {
+          position_ -= abs_n;
+          current_buffer_position_ -= abs_n;
+          return;
+        }
+
+        // Update position.
+        abs_n -= current_buffer_position_;
+        position_ -= current_buffer_position_;
+
+        // Check if we've reached the beginning of the buffers.
+        if (current_ == begin_)
+        {
+          BOOST_ASIO_ASSERT(abs_n == 0 && "iterator out of bounds");
+          current_buffer_position_ = 0;
+          return;
+        }
+
+        // Find the previous non-empty buffer.
+        buffer_sequence_iterator_type iter = current_;
+        while (iter != begin_)
+        {
+          --iter;
+          buffer_type buffer = *iter;
+          std::size_t buffer_size = buffer.size();
+          if (buffer_size > 0)
+          {
+            current_ = iter;
+            current_buffer_ = buffer;
+            current_buffer_position_ = buffer_size;
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  // Determine the distance between two iterators.
+  std::ptrdiff_t distance_to(const buffers_iterator& other) const
+  {
+    return other.position_ - position_;
+  }
+
+  buffer_type current_buffer_;
+  std::size_t current_buffer_position_;
+  buffer_sequence_iterator_type begin_;
+  buffer_sequence_iterator_type current_;
+  buffer_sequence_iterator_type end_;
+  std::size_t position_;
+};
+
+/// Construct an iterator representing the beginning of the buffers' data.
+template <typename BufferSequence>
+inline buffers_iterator<BufferSequence> buffers_begin(
+    const BufferSequence& buffers)
+{
+  return buffers_iterator<BufferSequence>::begin(buffers);
+}
+
+/// Construct an iterator representing the end of the buffers' data.
+template <typename BufferSequence>
+inline buffers_iterator<BufferSequence> buffers_end(
+    const BufferSequence& buffers)
+{
+  return buffers_iterator<BufferSequence>::end(buffers);
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BUFFERS_ITERATOR_HPP

+ 220 - 0
cpir-read/boost/boost/asio/completion_condition.hpp

@@ -0,0 +1,220 @@
+//
+// completion_condition.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_COMPLETION_CONDITION_HPP
+#define BOOST_ASIO_COMPLETION_CONDITION_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+namespace detail {
+
+// The default maximum number of bytes to transfer in a single operation.
+enum default_max_transfer_size_t { default_max_transfer_size = 65536 };
+
+// Adapt result of old-style completion conditions (which had a bool result
+// where true indicated that the operation was complete).
+inline std::size_t adapt_completion_condition_result(bool result)
+{
+  return result ? 0 : default_max_transfer_size;
+}
+
+// Adapt result of current completion conditions (which have a size_t result
+// where 0 means the operation is complete, and otherwise the result is the
+// maximum number of bytes to transfer on the next underlying operation).
+inline std::size_t adapt_completion_condition_result(std::size_t result)
+{
+  return result;
+}
+
+class transfer_all_t
+{
+public:
+  typedef std::size_t result_type;
+
+  template <typename Error>
+  std::size_t operator()(const Error& err, std::size_t)
+  {
+    return !!err ? 0 : default_max_transfer_size;
+  }
+};
+
+class transfer_at_least_t
+{
+public:
+  typedef std::size_t result_type;
+
+  explicit transfer_at_least_t(std::size_t minimum)
+    : minimum_(minimum)
+  {
+  }
+
+  template <typename Error>
+  std::size_t operator()(const Error& err, std::size_t bytes_transferred)
+  {
+    return (!!err || bytes_transferred >= minimum_)
+      ? 0 : default_max_transfer_size;
+  }
+
+private:
+  std::size_t minimum_;
+};
+
+class transfer_exactly_t
+{
+public:
+  typedef std::size_t result_type;
+
+  explicit transfer_exactly_t(std::size_t size)
+    : size_(size)
+  {
+  }
+
+  template <typename Error>
+  std::size_t operator()(const Error& err, std::size_t bytes_transferred)
+  {
+    return (!!err || bytes_transferred >= size_) ? 0 :
+      (size_ - bytes_transferred < default_max_transfer_size
+        ? size_ - bytes_transferred : std::size_t(default_max_transfer_size));
+  }
+
+private:
+  std::size_t size_;
+};
+
+} // namespace detail
+
+/**
+ * @defgroup completion_condition Completion Condition Function Objects
+ *
+ * Function objects used for determining when a read or write operation should
+ * complete.
+ */
+/*@{*/
+
+/// Return a completion condition function object that indicates that a read or
+/// write operation should continue until all of the data has been transferred,
+/// or until an error occurs.
+/**
+ * This function is used to create an object, of unspecified type, that meets
+ * CompletionCondition requirements.
+ *
+ * @par Example
+ * Reading until a buffer is full:
+ * @code
+ * boost::array<char, 128> buf;
+ * boost::system::error_code ec;
+ * std::size_t n = boost::asio::read(
+ *     sock, boost::asio::buffer(buf),
+ *     boost::asio::transfer_all(), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * }
+ * else
+ * {
+ *   // n == 128
+ * }
+ * @endcode
+ */
+#if defined(GENERATING_DOCUMENTATION)
+unspecified transfer_all();
+#else
+inline detail::transfer_all_t transfer_all()
+{
+  return detail::transfer_all_t();
+}
+#endif
+
+/// Return a completion condition function object that indicates that a read or
+/// write operation should continue until a minimum number of bytes has been
+/// transferred, or until an error occurs.
+/**
+ * This function is used to create an object, of unspecified type, that meets
+ * CompletionCondition requirements.
+ *
+ * @par Example
+ * Reading until a buffer is full or contains at least 64 bytes:
+ * @code
+ * boost::array<char, 128> buf;
+ * boost::system::error_code ec;
+ * std::size_t n = boost::asio::read(
+ *     sock, boost::asio::buffer(buf),
+ *     boost::asio::transfer_at_least(64), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * }
+ * else
+ * {
+ *   // n >= 64 && n <= 128
+ * }
+ * @endcode
+ */
+#if defined(GENERATING_DOCUMENTATION)
+unspecified transfer_at_least(std::size_t minimum);
+#else
+inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum)
+{
+  return detail::transfer_at_least_t(minimum);
+}
+#endif
+
+/// Return a completion condition function object that indicates that a read or
+/// write operation should continue until an exact number of bytes has been
+/// transferred, or until an error occurs.
+/**
+ * This function is used to create an object, of unspecified type, that meets
+ * CompletionCondition requirements.
+ *
+ * @par Example
+ * Reading until a buffer is full or contains exactly 64 bytes:
+ * @code
+ * boost::array<char, 128> buf;
+ * boost::system::error_code ec;
+ * std::size_t n = boost::asio::read(
+ *     sock, boost::asio::buffer(buf),
+ *     boost::asio::transfer_exactly(64), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * }
+ * else
+ * {
+ *   // n == 64
+ * }
+ * @endcode
+ */
+#if defined(GENERATING_DOCUMENTATION)
+unspecified transfer_exactly(std::size_t size);
+#else
+inline detail::transfer_exactly_t transfer_exactly(std::size_t size)
+{
+  return detail::transfer_exactly_t(size);
+}
+#endif
+
+/*@}*/
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_COMPLETION_CONDITION_HPP

+ 1061 - 0
cpir-read/boost/boost/asio/connect.hpp

@@ -0,0 +1,1061 @@
+//
+// connect.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_CONNECT_HPP
+#define BOOST_ASIO_CONNECT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+namespace detail
+{
+  char (&has_iterator_helper(...))[2];
+
+  template <typename T>
+  char has_iterator_helper(T*, typename T::iterator* = 0);
+
+  template <typename T>
+  struct has_iterator_typedef
+  {
+    enum { value = (sizeof((has_iterator_helper)((T*)(0))) == 1) };
+  };
+} // namespace detail
+
+/// Type trait used to determine whether a type is an endpoint sequence that can
+/// be used with with @c connect and @c async_connect.
+template <typename T>
+struct is_endpoint_sequence
+{
+#if defined(GENERATING_DOCUMENTATION)
+  /// The value member is true if the type may be used as an endpoint sequence.
+  static const bool value;
+#else
+  enum
+  {
+    value = detail::has_iterator_typedef<T>::value
+  };
+#endif
+};
+
+/**
+ * @defgroup connect boost::asio::connect
+ *
+ * @brief Establishes a socket connection by trying each endpoint in a sequence.
+ */
+/*@{*/
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @returns The successfully connected endpoint.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @par Example
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ * boost::asio::connect(s, r.resolve(q)); @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
+typename Protocol::endpoint connect(
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, the successfully connected endpoint. Otherwise, a
+ * default-constructed endpoint.
+ *
+ * @par Example
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ * boost::system::error_code ec;
+ * boost::asio::connect(s, r.resolve(q), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
+typename Protocol::endpoint connect(
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints, boost::system::error_code& ec,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, boost::system::error_code& ec,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @returns An iterator denoting the successfully connected endpoint.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @par Example
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * boost::asio::connect(s, e.begin(), e.end()); @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, Iterator end);
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @par Example
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * boost::system::error_code ec;
+ * boost::asio::connect(s, e.begin(), e.end(), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, Iterator end, boost::system::error_code& ec);
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @returns The successfully connected endpoint.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ * tcp::endpoint e = boost::asio::connect(s,
+ *     r.resolve(q), my_connect_condition());
+ * std::cout << "Connected to: " << e << std::endl; @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename EndpointSequence, typename ConnectCondition>
+typename Protocol::endpoint connect(
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints, ConnectCondition connect_condition,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, the successfully connected endpoint. Otherwise, a
+ * default-constructed endpoint.
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ * boost::system::error_code ec;
+ * tcp::endpoint e = boost::asio::connect(s,
+ *     r.resolve(q), my_connect_condition(), ec);
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * }
+ * else
+ * {
+ *   std::cout << "Connected to: " << e << std::endl;
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename EndpointSequence, typename ConnectCondition>
+typename Protocol::endpoint connect(
+    basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints, ConnectCondition connect_condition,
+    boost::system::error_code& ec,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename ConnectCondition>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, ConnectCondition connect_condition,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+
+/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename ConnectCondition>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+    ConnectCondition connect_condition, boost::system::error_code& ec,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @returns An iterator denoting the successfully connected endpoint.
+ *
+ * @throws boost::system::system_error Thrown on failure. If the sequence is
+ * empty, the associated @c error_code is boost::asio::error::not_found.
+ * Otherwise, contains the error from the last connection attempt.
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * tcp::resolver::results_type::iterator i = boost::asio::connect(
+ *     s, e.begin(), e.end(), my_connect_condition());
+ * std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename ConnectCondition>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+    Iterator end, ConnectCondition connect_condition);
+
+/// Establishes a socket connection by trying each endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c connect member
+ * function, once for each endpoint in the sequence, until a connection is
+ * successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param ec Set to indicate what error occurred, if any. If the sequence is
+ * empty, set to boost::asio::error::not_found. Otherwise, contains the error
+ * from the last connection attempt.
+ *
+ * @returns On success, an iterator denoting the successfully connected
+ * endpoint. Otherwise, the end iterator.
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::resolver::results_type e = r.resolve(q);
+ * tcp::socket s(io_context);
+ * boost::system::error_code ec;
+ * tcp::resolver::results_type::iterator i = boost::asio::connect(
+ *     s, e.begin(), e.end(), my_connect_condition());
+ * if (ec)
+ * {
+ *   // An error occurred.
+ * }
+ * else
+ * {
+ *   std::cout << "Connected to: " << i->endpoint() << std::endl;
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename ConnectCondition>
+Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, Iterator end, ConnectCondition connect_condition,
+    boost::system::error_code& ec);
+
+/*@}*/
+
+/**
+ * @defgroup async_connect boost::asio::async_connect
+ *
+ * @brief Asynchronously establishes a socket connection by trying each
+ * endpoint in a sequence.
+ */
+/*@{*/
+
+/// Asynchronously establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, the successfully connected endpoint.
+ *   // Otherwise, a default-constructed endpoint.
+ *   const typename Protocol::endpoint& endpoint
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ *
+ * // ...
+ *
+ * r.async_resolve(q, resolve_handler);
+ *
+ * // ...
+ *
+ * void resolve_handler(
+ *     const boost::system::error_code& ec,
+ *     tcp::resolver::results_type results)
+ * {
+ *   if (!ec)
+ *   {
+ *     boost::asio::async_connect(s, results, connect_handler);
+ *   }
+ * }
+ *
+ * // ...
+ *
+ * void connect_handler(
+ *     const boost::system::error_code& ec,
+ *     const tcp::endpoint& endpoint)
+ * {
+ *   // ...
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename EndpointSequence, typename RangeConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
+    void (boost::system::error_code, typename Protocol::endpoint))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints,
+    BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Asynchronously establishes a socket connection by trying each
+/// endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, an iterator denoting the successfully
+ *   // connected endpoint. Otherwise, the end iterator.
+ *   Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
+    void (boost::system::error_code, Iterator))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Asynchronously establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, an iterator denoting the successfully
+ *   // connected endpoint. Otherwise, the end iterator.
+ *   Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * @code std::vector<tcp::endpoint> endpoints = ...;
+ * tcp::socket s(io_context);
+ * boost::asio::async_connect(s,
+ *     endpoints.begin(), endpoints.end(),
+ *     connect_handler);
+ *
+ * // ...
+ *
+ * void connect_handler(
+ *     const boost::system::error_code& ec,
+ *     std::vector<tcp::endpoint>::iterator i)
+ * {
+ *   // ...
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+    typename Iterator, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
+    void (boost::system::error_code, Iterator))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, Iterator end,
+    BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
+
+/// Asynchronously establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param endpoints A sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, an iterator denoting the successfully
+ *   // connected endpoint. Otherwise, the end iterator.
+ *   Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ *
+ * // ...
+ *
+ * r.async_resolve(q, resolve_handler);
+ *
+ * // ...
+ *
+ * void resolve_handler(
+ *     const boost::system::error_code& ec,
+ *     tcp::resolver::results_type results)
+ * {
+ *   if (!ec)
+ *   {
+ *     boost::asio::async_connect(s, results,
+ *         my_connect_condition(),
+ *         connect_handler);
+ *   }
+ * }
+ *
+ * // ...
+ *
+ * void connect_handler(
+ *     const boost::system::error_code& ec,
+ *     const tcp::endpoint& endpoint)
+ * {
+ *   if (ec)
+ *   {
+ *     // An error occurred.
+ *   }
+ *   else
+ *   {
+ *     std::cout << "Connected to: " << endpoint << std::endl;
+ *   }
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
+    typename ConnectCondition, typename RangeConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
+    void (boost::system::error_code, typename Protocol::endpoint))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    const EndpointSequence& endpoints, ConnectCondition connect_condition,
+    BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
+    typename enable_if<is_endpoint_sequence<
+        EndpointSequence>::value>::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+/// (Deprecated.) Asynchronously establishes a socket connection by trying each
+/// endpoint in a sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, an iterator denoting the successfully
+ *   // connected endpoint. Otherwise, the end iterator.
+ *   Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @note This overload assumes that a default constructed object of type @c
+ * Iterator represents the end of the sequence. This is a valid assumption for
+ * iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+    typename ConnectCondition, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
+    void (boost::system::error_code, Iterator))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+    ConnectCondition connect_condition,
+    BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+    typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+/// Asynchronously establishes a socket connection by trying each endpoint in a
+/// sequence.
+/**
+ * This function attempts to connect a socket to one of a sequence of
+ * endpoints. It does this by repeated calls to the socket's @c async_connect
+ * member function, once for each endpoint in the sequence, until a connection
+ * is successfully established.
+ *
+ * @param s The socket to be connected. If the socket is already open, it will
+ * be closed.
+ *
+ * @param begin An iterator pointing to the start of a sequence of endpoints.
+ *
+ * @param end An iterator pointing to the end of a sequence of endpoints.
+ *
+ * @param connect_condition A function object that is called prior to each
+ * connection attempt. The signature of the function object must be:
+ * @code bool connect_condition(
+ *     const boost::system::error_code& ec,
+ *     const typename Protocol::endpoint& next); @endcode
+ * The @c ec parameter contains the result from the most recent connect
+ * operation. Before the first connection attempt, @c ec is always set to
+ * indicate success. The @c next parameter is the next endpoint to be tried.
+ * The function object should return true if the next endpoint should be tried,
+ * and false if it should be skipped.
+ *
+ * @param handler The handler to be called when the connect operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ *   // Result of operation. if the sequence is empty, set to
+ *   // boost::asio::error::not_found. Otherwise, contains the
+ *   // error from the last connection attempt.
+ *   const boost::system::error_code& error,
+ *
+ *   // On success, an iterator denoting the successfully
+ *   // connected endpoint. Otherwise, the end iterator.
+ *   Iterator iterator
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. Invocation
+ * of the handler will be performed in a manner equivalent to using
+ * boost::asio::io_context::post().
+ *
+ * @par Example
+ * The following connect condition function object can be used to output
+ * information about the individual connection attempts:
+ * @code struct my_connect_condition
+ * {
+ *   bool operator()(
+ *       const boost::system::error_code& ec,
+ *       const::tcp::endpoint& next)
+ *   {
+ *     if (ec) std::cout << "Error: " << ec.message() << std::endl;
+ *     std::cout << "Trying: " << next << std::endl;
+ *     return true;
+ *   }
+ * }; @endcode
+ * It would be used with the boost::asio::connect function as follows:
+ * @code tcp::resolver r(io_context);
+ * tcp::resolver::query q("host", "service");
+ * tcp::socket s(io_context);
+ *
+ * // ...
+ *
+ * r.async_resolve(q, resolve_handler);
+ *
+ * // ...
+ *
+ * void resolve_handler(
+ *     const boost::system::error_code& ec,
+ *     tcp::resolver::iterator i)
+ * {
+ *   if (!ec)
+ *   {
+ *     tcp::resolver::iterator end;
+ *     boost::asio::async_connect(s, i, end,
+ *         my_connect_condition(),
+ *         connect_handler);
+ *   }
+ * }
+ *
+ * // ...
+ *
+ * void connect_handler(
+ *     const boost::system::error_code& ec,
+ *     tcp::resolver::iterator i)
+ * {
+ *   if (ec)
+ *   {
+ *     // An error occurred.
+ *   }
+ *   else
+ *   {
+ *     std::cout << "Connected to: " << i->endpoint() << std::endl;
+ *   }
+ * } @endcode
+ */
+template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+    typename ConnectCondition, typename IteratorConnectHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
+    void (boost::system::error_code, Iterator))
+async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+    Iterator begin, Iterator end, ConnectCondition connect_condition,
+    BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
+
+/*@}*/
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/connect.hpp>
+
+#endif

+ 330 - 0
cpir-read/boost/boost/asio/coroutine.hpp

@@ -0,0 +1,330 @@
+//
+// coroutine.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_COROUTINE_HPP
+#define BOOST_ASIO_COROUTINE_HPP
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class coroutine_ref;
+
+} // namespace detail
+
+/// Provides support for implementing stackless coroutines.
+/**
+ * The @c coroutine class may be used to implement stackless coroutines. The
+ * class itself is used to store the current state of the coroutine.
+ *
+ * Coroutines are copy-constructible and assignable, and the space overhead is
+ * a single int. They can be used as a base class:
+ *
+ * @code class session : coroutine
+ * {
+ *   ...
+ * }; @endcode
+ *
+ * or as a data member:
+ *
+ * @code class session
+ * {
+ *   ...
+ *   coroutine coro_;
+ * }; @endcode
+ *
+ * or even bound in as a function argument using lambdas or @c bind(). The
+ * important thing is that as the application maintains a copy of the object
+ * for as long as the coroutine must be kept alive.
+ *
+ * @par Pseudo-keywords
+ *
+ * A coroutine is used in conjunction with certain "pseudo-keywords", which
+ * are implemented as macros. These macros are defined by a header file:
+ *
+ * @code #include <boost/asio/yield.hpp>@endcode
+ *
+ * and may conversely be undefined as follows:
+ *
+ * @code #include <boost/asio/unyield.hpp>@endcode
+ *
+ * <b>reenter</b>
+ *
+ * The @c reenter macro is used to define the body of a coroutine. It takes a
+ * single argument: a pointer or reference to a coroutine object. For example,
+ * if the base class is a coroutine object you may write:
+ *
+ * @code reenter (this)
+ * {
+ *   ... coroutine body ...
+ * } @endcode
+ *
+ * and if a data member or other variable you can write:
+ *
+ * @code reenter (coro_)
+ * {
+ *   ... coroutine body ...
+ * } @endcode
+ *
+ * When @c reenter is executed at runtime, control jumps to the location of the
+ * last @c yield or @c fork.
+ *
+ * The coroutine body may also be a single statement, such as:
+ *
+ * @code reenter (this) for (;;)
+ * {
+ *   ...
+ * } @endcode
+ *
+ * @b Limitation: The @c reenter macro is implemented using a switch. This
+ * means that you must take care when using local variables within the
+ * coroutine body. The local variable is not allowed in a position where
+ * reentering the coroutine could bypass the variable definition.
+ *
+ * <b>yield <em>statement</em></b>
+ *
+ * This form of the @c yield keyword is often used with asynchronous operations:
+ *
+ * @code yield socket_->async_read_some(buffer(*buffer_), *this); @endcode
+ *
+ * This divides into four logical steps:
+ *
+ * @li @c yield saves the current state of the coroutine.
+ * @li The statement initiates the asynchronous operation.
+ * @li The resume point is defined immediately following the statement.
+ * @li Control is transferred to the end of the coroutine body.
+ *
+ * When the asynchronous operation completes, the function object is invoked
+ * and @c reenter causes control to transfer to the resume point. It is
+ * important to remember to carry the coroutine state forward with the
+ * asynchronous operation. In the above snippet, the current class is a
+ * function object object with a coroutine object as base class or data member.
+ *
+ * The statement may also be a compound statement, and this permits us to
+ * define local variables with limited scope:
+ *
+ * @code yield
+ * {
+ *   mutable_buffers_1 b = buffer(*buffer_);
+ *   socket_->async_read_some(b, *this);
+ * } @endcode
+ *
+ * <b>yield return <em>expression</em> ;</b>
+ *
+ * This form of @c yield is often used in generators or coroutine-based parsers.
+ * For example, the function object:
+ *
+ * @code struct interleave : coroutine
+ * {
+ *   istream& is1;
+ *   istream& is2;
+ *   char operator()(char c)
+ *   {
+ *     reenter (this) for (;;)
+ *     {
+ *       yield return is1.get();
+ *       yield return is2.get();
+ *     }
+ *   }
+ * }; @endcode
+ *
+ * defines a trivial coroutine that interleaves the characters from two input
+ * streams.
+ *
+ * This type of @c yield divides into three logical steps:
+ *
+ * @li @c yield saves the current state of the coroutine.
+ * @li The resume point is defined immediately following the semicolon.
+ * @li The value of the expression is returned from the function.
+ *
+ * <b>yield ;</b>
+ *
+ * This form of @c yield is equivalent to the following steps:
+ *
+ * @li @c yield saves the current state of the coroutine.
+ * @li The resume point is defined immediately following the semicolon.
+ * @li Control is transferred to the end of the coroutine body.
+ *
+ * This form might be applied when coroutines are used for cooperative
+ * threading and scheduling is explicitly managed. For example:
+ *
+ * @code struct task : coroutine
+ * {
+ *   ...
+ *   void operator()()
+ *   {
+ *     reenter (this)
+ *     {
+ *       while (... not finished ...)
+ *       {
+ *         ... do something ...
+ *         yield;
+ *         ... do some more ...
+ *         yield;
+ *       }
+ *     }
+ *   }
+ *   ...
+ * };
+ * ...
+ * task t1, t2;
+ * for (;;)
+ * {
+ *   t1();
+ *   t2();
+ * } @endcode
+ *
+ * <b>yield break ;</b>
+ *
+ * The final form of @c yield is used to explicitly terminate the coroutine.
+ * This form is comprised of two steps:
+ *
+ * @li @c yield sets the coroutine state to indicate termination.
+ * @li Control is transferred to the end of the coroutine body.
+ *
+ * Once terminated, calls to is_complete() return true and the coroutine cannot
+ * be reentered.
+ *
+ * Note that a coroutine may also be implicitly terminated if the coroutine
+ * body is exited without a yield, e.g. by return, throw or by running to the
+ * end of the body.
+ *
+ * <b>fork <em>statement</em></b>
+ *
+ * The @c fork pseudo-keyword is used when "forking" a coroutine, i.e. splitting
+ * it into two (or more) copies. One use of @c fork is in a server, where a new
+ * coroutine is created to handle each client connection:
+ * 
+ * @code reenter (this)
+ * {
+ *   do
+ *   {
+ *     socket_.reset(new tcp::socket(io_context_));
+ *     yield acceptor->async_accept(*socket_, *this);
+ *     fork server(*this)();
+ *   } while (is_parent());
+ *   ... client-specific handling follows ...
+ * } @endcode
+ * 
+ * The logical steps involved in a @c fork are:
+ * 
+ * @li @c fork saves the current state of the coroutine.
+ * @li The statement creates a copy of the coroutine and either executes it
+ *     immediately or schedules it for later execution.
+ * @li The resume point is defined immediately following the semicolon.
+ * @li For the "parent", control immediately continues from the next line.
+ *
+ * The functions is_parent() and is_child() can be used to differentiate
+ * between parent and child. You would use these functions to alter subsequent
+ * control flow.
+ *
+ * Note that @c fork doesn't do the actual forking by itself. It is the
+ * application's responsibility to create a clone of the coroutine and call it.
+ * The clone can be called immediately, as above, or scheduled for delayed
+ * execution using something like io_context::post().
+ *
+ * @par Alternate macro names
+ *
+ * If preferred, an application can use macro names that follow a more typical
+ * naming convention, rather than the pseudo-keywords. These are:
+ *
+ * @li @c BOOST_ASIO_CORO_REENTER instead of @c reenter
+ * @li @c BOOST_ASIO_CORO_YIELD instead of @c yield
+ * @li @c BOOST_ASIO_CORO_FORK instead of @c fork
+ */
+class coroutine
+{
+public:
+  /// Constructs a coroutine in its initial state.
+  coroutine() : value_(0) {}
+
+  /// Returns true if the coroutine is the child of a fork.
+  bool is_child() const { return value_ < 0; }
+
+  /// Returns true if the coroutine is the parent of a fork.
+  bool is_parent() const { return !is_child(); }
+
+  /// Returns true if the coroutine has reached its terminal state.
+  bool is_complete() const { return value_ == -1; }
+
+private:
+  friend class detail::coroutine_ref;
+  int value_;
+};
+
+
+namespace detail {
+
+class coroutine_ref
+{
+public:
+  coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
+  coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
+  ~coroutine_ref() { if (!modified_) value_ = -1; }
+  operator int() const { return value_; }
+  int& operator=(int v) { modified_ = true; return value_ = v; }
+private:
+  void operator=(const coroutine_ref&);
+  int& value_;
+  bool modified_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#define BOOST_ASIO_CORO_REENTER(c) \
+  switch (::boost::asio::detail::coroutine_ref _coro_value = c) \
+    case -1: if (_coro_value) \
+    { \
+      goto terminate_coroutine; \
+      terminate_coroutine: \
+      _coro_value = -1; \
+      goto bail_out_of_coroutine; \
+      bail_out_of_coroutine: \
+      break; \
+    } \
+    else /* fall-through */ case 0:
+
+#define BOOST_ASIO_CORO_YIELD_IMPL(n) \
+  for (_coro_value = (n);;) \
+    if (_coro_value == 0) \
+    { \
+      case (n): ; \
+      break; \
+    } \
+    else \
+      switch (_coro_value ? 0 : 1) \
+        for (;;) \
+          /* fall-through */ case -1: if (_coro_value) \
+            goto terminate_coroutine; \
+          else for (;;) \
+            /* fall-through */ case 1: if (_coro_value) \
+              goto bail_out_of_coroutine; \
+            else /* fall-through */ case 0:
+
+#define BOOST_ASIO_CORO_FORK_IMPL(n) \
+  for (_coro_value = -(n);; _coro_value = (n)) \
+    if (_coro_value == (n)) \
+    { \
+      case -(n): ; \
+      break; \
+    } \
+    else
+
+#if defined(_MSC_VER)
+# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1)
+# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__COUNTER__ + 1)
+#else // defined(_MSC_VER)
+# define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__LINE__)
+# define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__LINE__)
+#endif // defined(_MSC_VER)
+
+#endif // BOOST_ASIO_COROUTINE_HPP

+ 468 - 0
cpir-read/boost/boost/asio/datagram_socket_service.hpp

@@ -0,0 +1,468 @@
+//
+// datagram_socket_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
+#define BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service.hpp>
+#endif
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Default service implementation for a datagram socket.
+template <typename Protocol>
+class datagram_socket_service
+#if defined(GENERATING_DOCUMENTATION)
+  : public boost::asio::io_context::service
+#else
+  : public boost::asio::detail::service_base<datagram_socket_service<Protocol> >
+#endif
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// The unique service identifier.
+  static boost::asio::io_context::id id;
+#endif
+
+  /// The protocol type.
+  typedef Protocol protocol_type;
+
+  /// The endpoint type.
+  typedef typename Protocol::endpoint endpoint_type;
+
+private:
+  // The type of the platform-specific implementation.
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  typedef detail::null_socket_service<Protocol> service_impl_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+  typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
+#else
+  typedef detail::reactive_socket_service<Protocol> service_impl_type;
+#endif
+
+public:
+  /// The type of a datagram socket.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined implementation_type;
+#else
+  typedef typename service_impl_type::implementation_type implementation_type;
+#endif
+
+  /// The native socket type.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined native_handle_type;
+#else
+  typedef typename service_impl_type::native_handle_type native_handle_type;
+#endif
+
+  /// Construct a new datagram socket service for the specified io_context.
+  explicit datagram_socket_service(boost::asio::io_context& io_context)
+    : boost::asio::detail::service_base<
+        datagram_socket_service<Protocol> >(io_context),
+      service_impl_(io_context)
+  {
+  }
+
+  /// Construct a new datagram socket implementation.
+  void construct(implementation_type& impl)
+  {
+    service_impl_.construct(impl);
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+  /// Move-construct a new datagram socket implementation.
+  void move_construct(implementation_type& impl,
+      implementation_type& other_impl)
+  {
+    service_impl_.move_construct(impl, other_impl);
+  }
+
+  /// Move-assign from another datagram socket implementation.
+  void move_assign(implementation_type& impl,
+      datagram_socket_service& other_service,
+      implementation_type& other_impl)
+  {
+    service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
+  }
+
+  // All socket services have access to each other's implementations.
+  template <typename Protocol1> friend class datagram_socket_service;
+
+  /// Move-construct a new datagram socket implementation from another protocol
+  /// type.
+  template <typename Protocol1>
+  void converting_move_construct(implementation_type& impl,
+      datagram_socket_service<Protocol1>& other_service,
+      typename datagram_socket_service<
+        Protocol1>::implementation_type& other_impl,
+      typename enable_if<is_convertible<
+        Protocol1, Protocol>::value>::type* = 0)
+  {
+    service_impl_.template converting_move_construct<Protocol1>(
+        impl, other_service.service_impl_, other_impl);
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+  /// Destroy a datagram socket implementation.
+  void destroy(implementation_type& impl)
+  {
+    service_impl_.destroy(impl);
+  }
+
+  // Open a new datagram socket implementation.
+  BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
+      const protocol_type& protocol, boost::system::error_code& ec)
+  {
+    if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM))
+      service_impl_.open(impl, protocol, ec);
+    else
+      ec = boost::asio::error::invalid_argument;
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Assign an existing native socket to a datagram socket.
+  BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
+      const protocol_type& protocol, const native_handle_type& native_socket,
+      boost::system::error_code& ec)
+  {
+    service_impl_.assign(impl, protocol, native_socket, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the socket is open.
+  bool is_open(const implementation_type& impl) const
+  {
+    return service_impl_.is_open(impl);
+  }
+
+  /// Close a datagram socket implementation.
+  BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    service_impl_.close(impl, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Release ownership of the underlying socket.
+  native_handle_type release(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.release(impl, ec);
+  }
+
+  /// Get the native socket implementation.
+  native_handle_type native_handle(implementation_type& impl)
+  {
+    return service_impl_.native_handle(impl);
+  }
+
+  /// Cancel all asynchronous operations associated with the socket.
+  BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    service_impl_.cancel(impl, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Determine whether the socket is at the out-of-band data mark.
+  bool at_mark(const implementation_type& impl,
+      boost::system::error_code& ec) const
+  {
+    return service_impl_.at_mark(impl, ec);
+  }
+
+  /// Determine the number of bytes available for reading.
+  std::size_t available(const implementation_type& impl,
+      boost::system::error_code& ec) const
+  {
+    return service_impl_.available(impl, ec);
+  }
+
+  // Bind the datagram socket to the specified local endpoint.
+  BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
+      const endpoint_type& endpoint, boost::system::error_code& ec)
+  {
+    service_impl_.bind(impl, endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Connect the datagram socket to the specified endpoint.
+  BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
+      const endpoint_type& peer_endpoint, boost::system::error_code& ec)
+  {
+    service_impl_.connect(impl, peer_endpoint, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Start an asynchronous connect.
+  template <typename ConnectHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
+      void (boost::system::error_code))
+  async_connect(implementation_type& impl,
+      const endpoint_type& peer_endpoint,
+      BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
+  {
+    async_completion<ConnectHandler,
+      void (boost::system::error_code)> init(handler);
+
+    service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
+
+    return init.result.get();
+  }
+
+  /// Set a socket option.
+  template <typename SettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
+      const SettableSocketOption& option, boost::system::error_code& ec)
+  {
+    service_impl_.set_option(impl, option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get a socket option.
+  template <typename GettableSocketOption>
+  BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
+      GettableSocketOption& option, boost::system::error_code& ec) const
+  {
+    service_impl_.get_option(impl, option, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Perform an IO control command on the socket.
+  template <typename IoControlCommand>
+  BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
+      IoControlCommand& command, boost::system::error_code& ec)
+  {
+    service_impl_.io_control(impl, command, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the socket.
+  bool non_blocking(const implementation_type& impl) const
+  {
+    return service_impl_.non_blocking(impl);
+  }
+
+  /// Sets the non-blocking mode of the socket.
+  BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
+      bool mode, boost::system::error_code& ec)
+  {
+    service_impl_.non_blocking(impl, mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Gets the non-blocking mode of the native socket implementation.
+  bool native_non_blocking(const implementation_type& impl) const
+  {
+    return service_impl_.native_non_blocking(impl);
+  }
+
+  /// Sets the non-blocking mode of the native socket implementation.
+  BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
+      bool mode, boost::system::error_code& ec)
+  {
+    service_impl_.native_non_blocking(impl, mode, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Get the local endpoint.
+  endpoint_type local_endpoint(const implementation_type& impl,
+      boost::system::error_code& ec) const
+  {
+    return service_impl_.local_endpoint(impl, ec);
+  }
+
+  /// Get the remote endpoint.
+  endpoint_type remote_endpoint(const implementation_type& impl,
+      boost::system::error_code& ec) const
+  {
+    return service_impl_.remote_endpoint(impl, ec);
+  }
+
+  /// Disable sends or receives on the socket.
+  BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
+      socket_base::shutdown_type what, boost::system::error_code& ec)
+  {
+    service_impl_.shutdown(impl, what, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Wait for the socket to become ready to read, ready to write, or to have
+  /// pending error conditions.
+  BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
+      socket_base::wait_type w, boost::system::error_code& ec)
+  {
+    service_impl_.wait(impl, w, ec);
+    BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+  }
+
+  /// Asynchronously wait for the socket to become ready to read, ready to
+  /// write, or to have pending error conditions.
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(implementation_type& impl, socket_base::wait_type w,
+      BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    service_impl_.async_wait(impl, w, init.completion_handler);
+
+    return init.result.get();
+  }
+
+  /// Send the given data to the peer.
+  template <typename ConstBufferSequence>
+  std::size_t send(implementation_type& impl,
+      const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return service_impl_.send(impl, buffers, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send(implementation_type& impl, const ConstBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    service_impl_.async_send(impl, buffers, flags, init.completion_handler);
+
+    return init.result.get();
+  }
+
+  /// Send a datagram to the specified endpoint.
+  template <typename ConstBufferSequence>
+  std::size_t send_to(implementation_type& impl,
+      const ConstBufferSequence& buffers, const endpoint_type& destination,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return service_impl_.send_to(impl, buffers, destination, flags, ec);
+  }
+
+  /// Start an asynchronous send.
+  template <typename ConstBufferSequence, typename WriteHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+      void (boost::system::error_code, std::size_t))
+  async_send_to(implementation_type& impl,
+      const ConstBufferSequence& buffers, const endpoint_type& destination,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
+  {
+    async_completion<WriteHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    service_impl_.async_send_to(impl, buffers,
+        destination, flags, init.completion_handler);
+
+    return init.result.get();
+  }
+
+  /// Receive some data from the peer.
+  template <typename MutableBufferSequence>
+  std::size_t receive(implementation_type& impl,
+      const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return service_impl_.receive(impl, buffers, flags, ec);
+  }
+
+  /// Start an asynchronous receive.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive(implementation_type& impl,
+      const MutableBufferSequence& buffers,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
+
+    return init.result.get();
+  }
+
+  /// Receive a datagram with the endpoint of the sender.
+  template <typename MutableBufferSequence>
+  std::size_t receive_from(implementation_type& impl,
+      const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
+      socket_base::message_flags flags, boost::system::error_code& ec)
+  {
+    return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
+        ec);
+  }
+
+  /// Start an asynchronous receive that will get the endpoint of the sender.
+  template <typename MutableBufferSequence, typename ReadHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+      void (boost::system::error_code, std::size_t))
+  async_receive_from(implementation_type& impl,
+      const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
+      socket_base::message_flags flags,
+      BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+  {
+    async_completion<ReadHandler,
+      void (boost::system::error_code, std::size_t)> init(handler);
+
+    service_impl_.async_receive_from(impl, buffers,
+        sender_endpoint, flags, init.completion_handler);
+
+    return init.result.get();
+  }
+
+private:
+  // Destroy all user-defined handler objects owned by the service.
+  void shutdown()
+  {
+    service_impl_.shutdown();
+  }
+
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP

+ 40 - 0
cpir-read/boost/boost/asio/deadline_timer.hpp

@@ -0,0 +1,40 @@
+//
+// deadline_timer.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DEADLINE_TIMER_HPP
+#define BOOST_ASIO_DEADLINE_TIMER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/socket_types.hpp> // Must come before posix_time.
+#include <boost/asio/basic_deadline_timer.hpp>
+
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Typedef for the typical usage of timer. Uses a UTC clock.
+typedef basic_deadline_timer<boost::posix_time::ptime> deadline_timer;
+
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_DEADLINE_TIMER_HPP

+ 175 - 0
cpir-read/boost/boost/asio/deadline_timer_service.hpp

@@ -0,0 +1,175 @@
+//
+// deadline_timer_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
+#define BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
+  || defined(GENERATING_DOCUMENTATION)
+
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/deadline_timer_service.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/time_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Default service implementation for a timer.
+template <typename TimeType,
+    typename TimeTraits = boost::asio::time_traits<TimeType> >
+class deadline_timer_service
+#if defined(GENERATING_DOCUMENTATION)
+  : public boost::asio::io_context::service
+#else
+  : public boost::asio::detail::service_base<
+      deadline_timer_service<TimeType, TimeTraits> >
+#endif
+{
+public:
+#if defined(GENERATING_DOCUMENTATION)
+  /// The unique service identifier.
+  static boost::asio::io_context::id id;
+#endif
+
+  /// The time traits type.
+  typedef TimeTraits traits_type;
+
+  /// The time type.
+  typedef typename traits_type::time_type time_type;
+
+  /// The duration type.
+  typedef typename traits_type::duration_type duration_type;
+
+private:
+  // The type of the platform-specific implementation.
+  typedef detail::deadline_timer_service<traits_type> service_impl_type;
+
+public:
+  /// The implementation type of the deadline timer.
+#if defined(GENERATING_DOCUMENTATION)
+  typedef implementation_defined implementation_type;
+#else
+  typedef typename service_impl_type::implementation_type implementation_type;
+#endif
+
+  /// Construct a new timer service for the specified io_context.
+  explicit deadline_timer_service(boost::asio::io_context& io_context)
+    : boost::asio::detail::service_base<
+        deadline_timer_service<TimeType, TimeTraits> >(io_context),
+      service_impl_(io_context)
+  {
+  }
+
+  /// Construct a new timer implementation.
+  void construct(implementation_type& impl)
+  {
+    service_impl_.construct(impl);
+  }
+
+  /// Destroy a timer implementation.
+  void destroy(implementation_type& impl)
+  {
+    service_impl_.destroy(impl);
+  }
+
+  /// Cancel any asynchronous wait operations associated with the timer.
+  std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
+  {
+    return service_impl_.cancel(impl, ec);
+  }
+
+  /// Cancels one asynchronous wait operation associated with the timer.
+  std::size_t cancel_one(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    return service_impl_.cancel_one(impl, ec);
+  }
+
+  /// Get the expiry time for the timer as an absolute time.
+  time_type expires_at(const implementation_type& impl) const
+  {
+    return service_impl_.expiry(impl);
+  }
+
+  /// Set the expiry time for the timer as an absolute time.
+  std::size_t expires_at(implementation_type& impl,
+      const time_type& expiry_time, boost::system::error_code& ec)
+  {
+    return service_impl_.expires_at(impl, expiry_time, ec);
+  }
+
+  /// Get the expiry time for the timer relative to now.
+  duration_type expires_from_now(const implementation_type& impl) const
+  {
+    return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
+  }
+
+  /// Set the expiry time for the timer relative to now.
+  std::size_t expires_from_now(implementation_type& impl,
+      const duration_type& expiry_time, boost::system::error_code& ec)
+  {
+    return service_impl_.expires_after(impl, expiry_time, ec);
+  }
+
+  // Perform a blocking wait on the timer.
+  void wait(implementation_type& impl, boost::system::error_code& ec)
+  {
+    service_impl_.wait(impl, ec);
+  }
+
+  // Start an asynchronous wait on the timer.
+  template <typename WaitHandler>
+  BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
+      void (boost::system::error_code))
+  async_wait(implementation_type& impl,
+      BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
+  {
+    async_completion<WaitHandler,
+      void (boost::system::error_code)> init(handler);
+
+    service_impl_.async_wait(impl, init.completion_handler);
+
+    return init.result.get();
+  }
+
+private:
+  // Destroy all user-defined handler objects owned by the service.
+  void shutdown()
+  {
+    service_impl_.shutdown();
+  }
+
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+       // || defined(GENERATING_DOCUMENTATION)
+
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP

+ 109 - 0
cpir-read/boost/boost/asio/defer.hpp

@@ -0,0 +1,109 @@
+//
+// defer.hpp
+// ~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DEFER_HPP
+#define BOOST_ASIO_DEFER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/is_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Submits a completion token or function object for execution.
+/**
+ * This function submits an object for execution using the object's associated
+ * executor. The function object is queued for execution, and is never called
+ * from the current thread prior to returning from <tt>defer()</tt>.
+ *
+ * This function has the following effects:
+ *
+ * @li Constructs a function object handler of type @c Handler, initialized
+ * with <tt>handler(forward<CompletionToken>(token))</tt>.
+ *
+ * @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
+ * initializing the object as <tt>result(handler)</tt>.
+ *
+ * @li Obtains the handler's associated executor object @c ex by performing
+ * <tt>get_associated_executor(handler)</tt>.
+ *
+ * @li Obtains the handler's associated allocator object @c alloc by performing
+ * <tt>get_associated_allocator(handler)</tt>.
+ *
+ * @li Performs <tt>ex.defer(std::move(handler), alloc)</tt>.
+ *
+ * @li Returns <tt>result.get()</tt>.
+ */
+template <typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+    BOOST_ASIO_MOVE_ARG(CompletionToken) token);
+
+/// Submits a completion token or function object for execution.
+/**
+ * This function submits an object for execution using the specified executor.
+ * The function object is queued for execution, and is never called from the
+ * current thread prior to returning from <tt>defer()</tt>.
+ *
+ * This function has the following effects:
+ *
+ * @li Constructs a function object handler of type @c Handler, initialized
+ * with <tt>handler(forward<CompletionToken>(token))</tt>.
+ *
+ * @li Constructs an object @c result of type <tt>async_result<Handler></tt>,
+ * initializing the object as <tt>result(handler)</tt>.
+ *
+ * @li Obtains the handler's associated executor object @c ex1 by performing
+ * <tt>get_associated_executor(handler)</tt>.
+ *
+ * @li Creates a work object @c w by performing <tt>make_work(ex1)</tt>.
+ *
+ * @li Obtains the handler's associated allocator object @c alloc by performing
+ * <tt>get_associated_allocator(handler)</tt>.
+ *
+ * @li Constructs a function object @c f with a function call operator that
+ * performs <tt>ex1.dispatch(std::move(handler), alloc)</tt> followed by
+ * <tt>w.reset()</tt>.
+ *
+ * @li Performs <tt>Executor(ex).defer(std::move(f), alloc)</tt>.
+ *
+ * @li Returns <tt>result.get()</tt>.
+ */
+template <typename Executor, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+    const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
+    typename enable_if<is_executor<Executor>::value>::type* = 0);
+
+/// Submits a completion token or function object for execution.
+/**
+ * @returns <tt>defer(ctx.get_executor(), forward<CompletionToken>(token))</tt>.
+ */
+template <typename ExecutionContext, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+    ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
+    typename enable_if<is_convertible<
+      ExecutionContext&, execution_context&>::value>::type* = 0);
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/defer.hpp>
+
+#endif // BOOST_ASIO_DEFER_HPP

+ 40 - 0
cpir-read/boost/boost/asio/detail/array.hpp

@@ -0,0 +1,40 @@
+//
+// detail/array.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_ARRAY_HPP
+#define BOOST_ASIO_DETAIL_ARRAY_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+# include <array>
+#else // defined(BOOST_ASIO_HAS_STD_ARRAY)
+# include <boost/array.hpp>
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+using std::array;
+#else // defined(BOOST_ASIO_HAS_STD_ARRAY)
+using boost::array;
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_ARRAY_HPP

+ 34 - 0
cpir-read/boost/boost/asio/detail/array_fwd.hpp

@@ -0,0 +1,34 @@
+//
+// detail/array_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_ARRAY_FWD_HPP
+#define BOOST_ASIO_DETAIL_ARRAY_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+namespace boost {
+
+template<class T, std::size_t N>
+class array;
+
+} // namespace boost
+
+// Standard library components can't be forward declared, so we'll have to
+// include the array header. Fortunately, it's fairly lightweight and doesn't
+// add significantly to the compile time.
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+# include <array>
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+#endif // BOOST_ASIO_DETAIL_ARRAY_FWD_HPP

+ 32 - 0
cpir-read/boost/boost/asio/detail/assert.hpp

@@ -0,0 +1,32 @@
+//
+// detail/assert.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_ASSERT_HPP
+#define BOOST_ASIO_DETAIL_ASSERT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+# include <boost/assert.hpp>
+#else // defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+# include <cassert>
+#endif // defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+
+#if defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+# define BOOST_ASIO_ASSERT(expr) BOOST_ASSERT(expr)
+#else // defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+# define BOOST_ASIO_ASSERT(expr) assert(expr)
+#endif // defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+
+#endif // BOOST_ASIO_DETAIL_ASSERT_HPP

+ 47 - 0
cpir-read/boost/boost/asio/detail/atomic_count.hpp

@@ -0,0 +1,47 @@
+//
+// detail/atomic_count.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_ATOMIC_COUNT_HPP
+#define BOOST_ASIO_DETAIL_ATOMIC_COUNT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_THREADS)
+// Nothing to include.
+#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
+# include <atomic>
+#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
+# include <boost/detail/atomic_count.hpp>
+#endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if !defined(BOOST_ASIO_HAS_THREADS)
+typedef long atomic_count;
+inline void increment(atomic_count& a, long b) { a += b; }
+#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
+typedef std::atomic<long> atomic_count;
+inline void increment(atomic_count& a, long b) { a += b; }
+#else // defined(BOOST_ASIO_HAS_STD_ATOMIC)
+typedef boost::detail::atomic_count atomic_count;
+inline void increment(atomic_count& a, long b) { while (b > 0) ++a, --b; }
+#endif // defined(BOOST_ASIO_HAS_STD_ATOMIC)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_ATOMIC_COUNT_HPP

+ 70 - 0
cpir-read/boost/boost/asio/detail/base_from_completion_cond.hpp

@@ -0,0 +1,70 @@
+//
+// detail/base_from_completion_cond.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP
+#define BOOST_ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/completion_condition.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename CompletionCondition>
+class base_from_completion_cond
+{
+protected:
+  explicit base_from_completion_cond(CompletionCondition completion_condition)
+    : completion_condition_(completion_condition)
+  {
+  }
+
+  std::size_t check_for_completion(
+      const boost::system::error_code& ec,
+      std::size_t total_transferred)
+  {
+    return detail::adapt_completion_condition_result(
+        completion_condition_(ec, total_transferred));
+  }
+
+private:
+  CompletionCondition completion_condition_;
+};
+
+template <>
+class base_from_completion_cond<transfer_all_t>
+{
+protected:
+  explicit base_from_completion_cond(transfer_all_t)
+  {
+  }
+
+  static std::size_t check_for_completion(
+      const boost::system::error_code& ec,
+      std::size_t total_transferred)
+  {
+    return transfer_all_t()(ec, total_transferred);
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP

+ 818 - 0
cpir-read/boost/boost/asio/detail/bind_handler.hpp

@@ -0,0 +1,818 @@
+//
+// detail/bind_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
+#define BOOST_ASIO_DETAIL_BIND_HANDLER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/associated_allocator.hpp>
+#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_cont_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler, typename Arg1>
+class binder1
+{
+public:
+  template <typename T>
+  binder1(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1)
+    : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
+      arg1_(arg1)
+  {
+  }
+
+  binder1(Handler& handler, const Arg1& arg1)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  binder1(const binder1& other)
+    : handler_(other.handler_),
+      arg1_(other.arg1_)
+  {
+  }
+
+  binder1(binder1&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_));
+  }
+
+  void operator()() const
+  {
+    handler_(arg1_);
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+};
+
+template <typename Handler, typename Arg1>
+inline void* asio_handler_allocate(std::size_t size,
+    binder1<Handler, Arg1>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    binder1<Handler, Arg1>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline bool asio_handler_is_continuation(
+    binder1<Handler, Arg1>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1>
+inline void asio_handler_invoke(Function& function,
+    binder1<Handler, Arg1>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1>
+inline void asio_handler_invoke(const Function& function,
+    binder1<Handler, Arg1>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline binder1<typename decay<Handler>::type, Arg1> bind_handler(
+    BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1)
+{
+  return binder1<typename decay<Handler>::type, Arg1>(0,
+      BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+class binder2
+{
+public:
+  template <typename T>
+  binder2(int, BOOST_ASIO_MOVE_ARG(T) handler,
+      const Arg1& arg1, const Arg2& arg2)
+    : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
+      arg1_(arg1),
+      arg2_(arg2)
+  {
+  }
+
+  binder2(Handler& handler, const Arg1& arg1, const Arg2& arg2)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1),
+      arg2_(arg2)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  binder2(const binder2& other)
+    : handler_(other.handler_),
+      arg1_(other.arg1_),
+      arg2_(other.arg2_)
+  {
+  }
+
+  binder2(binder2&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_),
+        static_cast<const Arg2&>(arg2_));
+  }
+
+  void operator()() const
+  {
+    handler_(arg1_, arg2_);
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+};
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void* asio_handler_allocate(std::size_t size,
+    binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline bool asio_handler_is_continuation(
+    binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_invoke(Function& function,
+    binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_invoke(const Function& function,
+    binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline binder2<typename decay<Handler>::type, Arg1, Arg2> bind_handler(
+    BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2)
+{
+  return binder2<typename decay<Handler>::type, Arg1, Arg2>(0,
+      BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2);
+}
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+class binder3
+{
+public:
+  template <typename T>
+  binder3(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+      const Arg2& arg2, const Arg3& arg3)
+    : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3)
+  {
+  }
+
+  binder3(Handler& handler, const Arg1& arg1,
+      const Arg2& arg2, const Arg3& arg3)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  binder3(const binder3& other)
+    : handler_(other.handler_),
+      arg1_(other.arg1_),
+      arg2_(other.arg2_),
+      arg3_(other.arg3_)
+  {
+  }
+
+  binder3(binder3&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+      arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_))
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_),
+        static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_));
+  }
+
+  void operator()() const
+  {
+    handler_(arg1_, arg2_, arg3_);
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+  Arg3 arg3_;
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+inline void* asio_handler_allocate(std::size_t size,
+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+inline bool asio_handler_is_continuation(
+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler,
+    typename Arg1, typename Arg2, typename Arg3>
+inline void asio_handler_invoke(Function& function,
+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Function, typename Handler,
+    typename Arg1, typename Arg2, typename Arg3>
+inline void asio_handler_invoke(const Function& function,
+    binder3<Handler, Arg1, Arg2, Arg3>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2, typename Arg3>
+inline binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3> bind_handler(
+    BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1, const Arg2& arg2,
+    const Arg3& arg3)
+{
+  return binder3<typename decay<Handler>::type, Arg1, Arg2, Arg3>(0,
+      BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3);
+}
+
+template <typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+class binder4
+{
+public:
+  template <typename T>
+  binder4(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+      const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
+    : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3),
+      arg4_(arg4)
+  {
+  }
+
+  binder4(Handler& handler, const Arg1& arg1,
+      const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3),
+      arg4_(arg4)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  binder4(const binder4& other)
+    : handler_(other.handler_),
+      arg1_(other.arg1_),
+      arg2_(other.arg2_),
+      arg3_(other.arg3_),
+      arg4_(other.arg4_)
+  {
+  }
+
+  binder4(binder4&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+      arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
+      arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_))
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_),
+        static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
+        static_cast<const Arg4&>(arg4_));
+  }
+
+  void operator()() const
+  {
+    handler_(arg1_, arg2_, arg3_, arg4_);
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+  Arg3 arg3_;
+  Arg4 arg4_;
+};
+
+template <typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline void* asio_handler_allocate(std::size_t size,
+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline bool asio_handler_is_continuation(
+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline void asio_handler_invoke(Function& function,
+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline void asio_handler_invoke(const Function& function,
+    binder4<Handler, Arg1, Arg2, Arg3, Arg4>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4>
+inline binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>
+bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
+    const Arg2& arg2, const Arg3& arg3, const Arg4& arg4)
+{
+  return binder4<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4>(0,
+      BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4);
+}
+
+template <typename Handler, typename Arg1, typename Arg2,
+    typename Arg3, typename Arg4, typename Arg5>
+class binder5
+{
+public:
+  template <typename T>
+  binder5(int, BOOST_ASIO_MOVE_ARG(T) handler, const Arg1& arg1,
+      const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+    : handler_(BOOST_ASIO_MOVE_CAST(T)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3),
+      arg4_(arg4),
+      arg5_(arg5)
+  {
+  }
+
+  binder5(Handler& handler, const Arg1& arg1, const Arg2& arg2,
+      const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1),
+      arg2_(arg2),
+      arg3_(arg3),
+      arg4_(arg4),
+      arg5_(arg5)
+  {
+  }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+  binder5(const binder5& other)
+    : handler_(other.handler_),
+      arg1_(other.arg1_),
+      arg2_(other.arg2_),
+      arg3_(other.arg3_),
+      arg4_(other.arg4_),
+      arg5_(other.arg5_)
+  {
+  }
+
+  binder5(binder5&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_)),
+      arg3_(BOOST_ASIO_MOVE_CAST(Arg3)(other.arg3_)),
+      arg4_(BOOST_ASIO_MOVE_CAST(Arg4)(other.arg4_)),
+      arg5_(BOOST_ASIO_MOVE_CAST(Arg5)(other.arg5_))
+  {
+  }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_),
+        static_cast<const Arg2&>(arg2_), static_cast<const Arg3&>(arg3_),
+        static_cast<const Arg4&>(arg4_), static_cast<const Arg5&>(arg5_));
+  }
+
+  void operator()() const
+  {
+    handler_(arg1_, arg2_, arg3_, arg4_, arg5_);
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+  Arg3 arg3_;
+  Arg4 arg4_;
+  Arg5 arg5_;
+};
+
+template <typename Handler, typename Arg1, typename Arg2,
+    typename Arg3, typename Arg4, typename Arg5>
+inline void* asio_handler_allocate(std::size_t size,
+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2,
+    typename Arg3, typename Arg4, typename Arg5>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2,
+    typename Arg3, typename Arg4, typename Arg5>
+inline bool asio_handler_is_continuation(
+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+inline void asio_handler_invoke(Function& function,
+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1,
+    typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+inline void asio_handler_invoke(const Function& function,
+    binder5<Handler, Arg1, Arg2, Arg3, Arg4, Arg5>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      function, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2,
+    typename Arg3, typename Arg4, typename Arg5>
+inline binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>
+bind_handler(BOOST_ASIO_MOVE_ARG(Handler) handler, const Arg1& arg1,
+    const Arg2& arg2, const Arg3& arg3, const Arg4& arg4, const Arg5& arg5)
+{
+  return binder5<typename decay<Handler>::type, Arg1, Arg2, Arg3, Arg4, Arg5>(0,
+      BOOST_ASIO_MOVE_CAST(Handler)(handler), arg1, arg2, arg3, arg4, arg5);
+}
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+
+template <typename Handler, typename Arg1>
+class move_binder1
+{
+public:
+  move_binder1(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
+      BOOST_ASIO_MOVE_ARG(Arg1) arg1)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1))
+  {
+  }
+
+  move_binder1(move_binder1&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_))
+  {
+  }
+
+  void operator()()
+  {
+    handler_(BOOST_ASIO_MOVE_CAST(Arg1)(arg1_));
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+};
+
+template <typename Handler, typename Arg1>
+inline void* asio_handler_allocate(std::size_t size,
+    move_binder1<Handler, Arg1>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    move_binder1<Handler, Arg1>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1>
+inline bool asio_handler_is_continuation(
+    move_binder1<Handler, Arg1>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1>
+inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
+    move_binder1<Handler, Arg1>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+class move_binder2
+{
+public:
+  move_binder2(int, BOOST_ASIO_MOVE_ARG(Handler) handler,
+      const Arg1& arg1, BOOST_ASIO_MOVE_ARG(Arg2) arg2)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+      arg1_(arg1),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(arg2))
+  {
+  }
+
+  move_binder2(move_binder2&& other)
+    : handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+      arg1_(BOOST_ASIO_MOVE_CAST(Arg1)(other.arg1_)),
+      arg2_(BOOST_ASIO_MOVE_CAST(Arg2)(other.arg2_))
+  {
+  }
+
+  void operator()()
+  {
+    handler_(static_cast<const Arg1&>(arg1_),
+        BOOST_ASIO_MOVE_CAST(Arg2)(arg2_));
+  }
+
+//private:
+  Handler handler_;
+  Arg1 arg1_;
+  Arg2 arg2_;
+};
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void* asio_handler_allocate(std::size_t size,
+    move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  return boost_asio_handler_alloc_helpers::allocate(
+      size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_deallocate(void* pointer, std::size_t size,
+    move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  boost_asio_handler_alloc_helpers::deallocate(
+      pointer, size, this_handler->handler_);
+}
+
+template <typename Handler, typename Arg1, typename Arg2>
+inline bool asio_handler_is_continuation(
+    move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  return boost_asio_handler_cont_helpers::is_continuation(
+      this_handler->handler_);
+}
+
+template <typename Function, typename Handler, typename Arg1, typename Arg2>
+inline void asio_handler_invoke(BOOST_ASIO_MOVE_ARG(Function) function,
+    move_binder2<Handler, Arg1, Arg2>* this_handler)
+{
+  boost_asio_handler_invoke_helpers::invoke(
+      BOOST_ASIO_MOVE_CAST(Function)(function), this_handler->handler_);
+}
+
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+} // namespace detail
+
+template <typename Handler, typename Arg1, typename Allocator>
+struct associated_allocator<detail::binder1<Handler, Arg1>, Allocator>
+{
+  typedef typename associated_allocator<Handler, Allocator>::type type;
+
+  static type get(const detail::binder1<Handler, Arg1>& h,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
+struct associated_allocator<detail::binder2<Handler, Arg1, Arg2>, Allocator>
+{
+  typedef typename associated_allocator<Handler, Allocator>::type type;
+
+  static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Executor>
+struct associated_executor<detail::binder1<Handler, Arg1>, Executor>
+{
+  typedef typename associated_executor<Handler, Executor>::type type;
+
+  static type get(const detail::binder1<Handler, Arg1>& h,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_executor<Handler, Executor>::get(h.handler_, ex);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Executor>
+struct associated_executor<detail::binder2<Handler, Arg1, Arg2>, Executor>
+{
+  typedef typename associated_executor<Handler, Executor>::type type;
+
+  static type get(const detail::binder2<Handler, Arg1, Arg2>& h,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_executor<Handler, Executor>::get(h.handler_, ex);
+  }
+};
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+
+template <typename Handler, typename Arg1, typename Allocator>
+struct associated_allocator<detail::move_binder1<Handler, Arg1>, Allocator>
+{
+  typedef typename associated_allocator<Handler, Allocator>::type type;
+
+  static type get(const detail::move_binder1<Handler, Arg1>& h,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Allocator>
+struct associated_allocator<
+    detail::move_binder2<Handler, Arg1, Arg2>, Allocator>
+{
+  typedef typename associated_allocator<Handler, Allocator>::type type;
+
+  static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
+      const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_allocator<Handler, Allocator>::get(h.handler_, a);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Executor>
+struct associated_executor<detail::move_binder1<Handler, Arg1>, Executor>
+{
+  typedef typename associated_executor<Handler, Executor>::type type;
+
+  static type get(const detail::move_binder1<Handler, Arg1>& h,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_executor<Handler, Executor>::get(h.handler_, ex);
+  }
+};
+
+template <typename Handler, typename Arg1, typename Arg2, typename Executor>
+struct associated_executor<detail::move_binder2<Handler, Arg1, Arg2>, Executor>
+{
+  typedef typename associated_executor<Handler, Executor>::type type;
+
+  static type get(const detail::move_binder2<Handler, Arg1, Arg2>& h,
+      const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+  {
+    return associated_executor<Handler, Executor>::get(h.handler_, ex);
+  }
+};
+
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BIND_HANDLER_HPP

+ 68 - 0
cpir-read/boost/boost/asio/detail/buffer_resize_guard.hpp

@@ -0,0 +1,68 @@
+//
+// detail/buffer_resize_guard.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP
+#define BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/limits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Helper class to manage buffer resizing in an exception safe way.
+template <typename Buffer>
+class buffer_resize_guard
+{
+public:
+  // Constructor.
+  buffer_resize_guard(Buffer& buffer)
+    : buffer_(buffer),
+      old_size_(buffer.size())
+  {
+  }
+
+  // Destructor rolls back the buffer resize unless commit was called.
+  ~buffer_resize_guard()
+  {
+    if (old_size_ != (std::numeric_limits<size_t>::max)())
+    {
+      buffer_.resize(old_size_);
+    }
+  }
+
+  // Commit the resize transaction.
+  void commit()
+  {
+    old_size_ = (std::numeric_limits<size_t>::max)();
+  }
+
+private:
+  // The buffer being managed.
+  Buffer& buffer_;
+
+  // The size of the buffer at the time the guard was constructed.
+  size_t old_size_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BUFFER_RESIZE_GUARD_HPP

+ 546 - 0
cpir-read/boost/boost/asio/detail/buffer_sequence_adapter.hpp

@@ -0,0 +1,546 @@
+//
+// detail/buffer_sequence_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
+#define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/array_fwd.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class buffer_sequence_adapter_base
+{
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+public:
+  // The maximum number of buffers to support in a single operation.
+  enum { max_buffers = 1 };
+
+protected:
+  typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
+
+  BOOST_ASIO_DECL static void init_native_buffer(
+      native_buffer_type& buf,
+      const boost::asio::mutable_buffer& buffer);
+
+  BOOST_ASIO_DECL static void init_native_buffer(
+      native_buffer_type& buf,
+      const boost::asio::const_buffer& buffer);
+#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+public:
+  // The maximum number of buffers to support in a single operation.
+  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
+
+protected:
+  typedef WSABUF native_buffer_type;
+
+  static void init_native_buffer(WSABUF& buf,
+      const boost::asio::mutable_buffer& buffer)
+  {
+    buf.buf = static_cast<char*>(buffer.data());
+    buf.len = static_cast<ULONG>(buffer.size());
+  }
+
+  static void init_native_buffer(WSABUF& buf,
+      const boost::asio::const_buffer& buffer)
+  {
+    buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
+    buf.len = static_cast<ULONG>(buffer.size());
+  }
+#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+public:
+  // The maximum number of buffers to support in a single operation.
+  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
+
+protected:
+  typedef iovec native_buffer_type;
+
+  static void init_iov_base(void*& base, void* addr)
+  {
+    base = addr;
+  }
+
+  template <typename T>
+  static void init_iov_base(T& base, void* addr)
+  {
+    base = static_cast<T>(addr);
+  }
+
+  static void init_native_buffer(iovec& iov,
+      const boost::asio::mutable_buffer& buffer)
+  {
+    init_iov_base(iov.iov_base, buffer.data());
+    iov.iov_len = buffer.size();
+  }
+
+  static void init_native_buffer(iovec& iov,
+      const boost::asio::const_buffer& buffer)
+  {
+    init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
+    iov.iov_len = buffer.size();
+  }
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+};
+
+// Helper class to translate buffers into the native buffer representation.
+template <typename Buffer, typename Buffers>
+class buffer_sequence_adapter
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
+    : count_(0), total_buffer_size_(0)
+  {
+    buffer_sequence_adapter::init(
+        boost::asio::buffer_sequence_begin(buffer_sequence),
+        boost::asio::buffer_sequence_end(buffer_sequence));
+  }
+
+  native_buffer_type* buffers()
+  {
+    return buffers_;
+  }
+
+  std::size_t count() const
+  {
+    return count_;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const Buffers& buffer_sequence)
+  {
+    return buffer_sequence_adapter::all_empty(
+        boost::asio::buffer_sequence_begin(buffer_sequence),
+        boost::asio::buffer_sequence_end(buffer_sequence));
+  }
+
+  static void validate(const Buffers& buffer_sequence)
+  {
+    buffer_sequence_adapter::validate(
+        boost::asio::buffer_sequence_begin(buffer_sequence),
+        boost::asio::buffer_sequence_end(buffer_sequence));
+  }
+
+  static Buffer first(const Buffers& buffer_sequence)
+  {
+    return buffer_sequence_adapter::first(
+        boost::asio::buffer_sequence_begin(buffer_sequence),
+        boost::asio::buffer_sequence_end(buffer_sequence));
+  }
+
+private:
+  template <typename Iterator>
+  void init(Iterator begin, Iterator end)
+  {
+    Iterator iter = begin;
+    for (; iter != end && count_ < max_buffers; ++iter, ++count_)
+    {
+      Buffer buffer(*iter);
+      init_native_buffer(buffers_[count_], buffer);
+      total_buffer_size_ += buffer.size();
+    }
+  }
+
+  template <typename Iterator>
+  static bool all_empty(Iterator begin, Iterator end)
+  {
+    Iterator iter = begin;
+    std::size_t i = 0;
+    for (; iter != end && i < max_buffers; ++iter, ++i)
+      if (Buffer(*iter).size() > 0)
+        return false;
+    return true;
+  }
+
+  template <typename Iterator>
+  static void validate(Iterator begin, Iterator end)
+  {
+    Iterator iter = begin;
+    for (; iter != end; ++iter)
+    {
+      Buffer buffer(*iter);
+      buffer.data();
+    }
+  }
+
+  template <typename Iterator>
+  static Buffer first(Iterator begin, Iterator end)
+  {
+    Iterator iter = begin;
+    for (; iter != end; ++iter)
+    {
+      Buffer buffer(*iter);
+      if (buffer.size() != 0)
+        return buffer;
+    }
+    return Buffer();
+  }
+
+  native_buffer_type buffers_[max_buffers];
+  std::size_t count_;
+  std::size_t total_buffer_size_;
+};
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffer>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::mutable_buffer& buffer_sequence)
+  {
+    init_native_buffer(buffer_, Buffer(buffer_sequence));
+    total_buffer_size_ = buffer_sequence.size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::mutable_buffer& buffer_sequence)
+  {
+    return buffer_sequence.size() == 0;
+  }
+
+  static void validate(const boost::asio::mutable_buffer& buffer_sequence)
+  {
+    buffer_sequence.data();
+  }
+
+  static Buffer first(const boost::asio::mutable_buffer& buffer_sequence)
+  {
+    return Buffer(buffer_sequence);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::const_buffer>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::const_buffer& buffer_sequence)
+  {
+    init_native_buffer(buffer_, Buffer(buffer_sequence));
+    total_buffer_size_ = buffer_sequence.size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::const_buffer& buffer_sequence)
+  {
+    return buffer_sequence.size() == 0;
+  }
+
+  static void validate(const boost::asio::const_buffer& buffer_sequence)
+  {
+    buffer_sequence.data();
+  }
+
+  static Buffer first(const boost::asio::const_buffer& buffer_sequence)
+  {
+    return Buffer(buffer_sequence);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::mutable_buffers_1& buffer_sequence)
+  {
+    init_native_buffer(buffer_, Buffer(buffer_sequence));
+    total_buffer_size_ = buffer_sequence.size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence)
+  {
+    return buffer_sequence.size() == 0;
+  }
+
+  static void validate(const boost::asio::mutable_buffers_1& buffer_sequence)
+  {
+    buffer_sequence.data();
+  }
+
+  static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence)
+  {
+    return Buffer(buffer_sequence);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::const_buffers_1>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::const_buffers_1& buffer_sequence)
+  {
+    init_native_buffer(buffer_, Buffer(buffer_sequence));
+    total_buffer_size_ = buffer_sequence.size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence)
+  {
+    return buffer_sequence.size() == 0;
+  }
+
+  static void validate(const boost::asio::const_buffers_1& buffer_sequence)
+  {
+    buffer_sequence.data();
+  }
+
+  static Buffer first(const boost::asio::const_buffers_1& buffer_sequence)
+  {
+    return Buffer(buffer_sequence);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename Buffer, typename Elem>
+class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::array<Elem, 2>& buffer_sequence)
+  {
+    init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
+    init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
+    total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return buffers_;
+  }
+
+  std::size_t count() const
+  {
+    return 2;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
+  {
+    return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
+  }
+
+  static void validate(const boost::array<Elem, 2>& buffer_sequence)
+  {
+    buffer_sequence[0].data();
+    buffer_sequence[1].data();
+  }
+
+  static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
+  {
+    return Buffer(buffer_sequence[0].size() != 0
+        ? buffer_sequence[0] : buffer_sequence[1]);
+  }
+
+private:
+  native_buffer_type buffers_[2];
+  std::size_t total_buffer_size_;
+};
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+template <typename Buffer, typename Elem>
+class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const std::array<Elem, 2>& buffer_sequence)
+  {
+    init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
+    init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
+    total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
+  }
+
+  native_buffer_type* buffers()
+  {
+    return buffers_;
+  }
+
+  std::size_t count() const
+  {
+    return 2;
+  }
+
+  std::size_t total_size() const
+  {
+    return total_buffer_size_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
+  {
+    return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
+  }
+
+  static void validate(const std::array<Elem, 2>& buffer_sequence)
+  {
+    buffer_sequence[0].data();
+    buffer_sequence[1].data();
+  }
+
+  static Buffer first(const std::array<Elem, 2>& buffer_sequence)
+  {
+    return Buffer(buffer_sequence[0].size() != 0
+        ? buffer_sequence[0] : buffer_sequence[1]);
+  }
+
+private:
+  native_buffer_type buffers_[2];
+  std::size_t total_buffer_size_;
+};
+
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/buffer_sequence_adapter.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP

+ 128 - 0
cpir-read/boost/boost/asio/detail/buffered_stream_storage.hpp

@@ -0,0 +1,128 @@
+//
+// detail/buffered_stream_storage.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP
+#define BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/assert.hpp>
+#include <cstddef>
+#include <cstring>
+#include <vector>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class buffered_stream_storage
+{
+public:
+  // The type of the bytes stored in the buffer.
+  typedef unsigned char byte_type;
+
+  // The type used for offsets into the buffer.
+  typedef std::size_t size_type;
+
+  // Constructor.
+  explicit buffered_stream_storage(std::size_t buffer_capacity)
+    : begin_offset_(0),
+      end_offset_(0),
+      buffer_(buffer_capacity)
+  {
+  }
+
+  /// Clear the buffer.
+  void clear()
+  {
+    begin_offset_ = 0;
+    end_offset_ = 0;
+  }
+
+  // Return a pointer to the beginning of the unread data.
+  mutable_buffer data()
+  {
+    return boost::asio::buffer(buffer_) + begin_offset_;
+  }
+
+  // Return a pointer to the beginning of the unread data.
+  const_buffer data() const
+  {
+    return boost::asio::buffer(buffer_) + begin_offset_;
+  }
+
+  // Is there no unread data in the buffer.
+  bool empty() const
+  {
+    return begin_offset_ == end_offset_;
+  }
+
+  // Return the amount of unread data the is in the buffer.
+  size_type size() const
+  {
+    return end_offset_ - begin_offset_;
+  }
+
+  // Resize the buffer to the specified length.
+  void resize(size_type length)
+  {
+    BOOST_ASIO_ASSERT(length <= capacity());
+    if (begin_offset_ + length <= capacity())
+    {
+      end_offset_ = begin_offset_ + length;
+    }
+    else
+    {
+      using namespace std; // For memmove.
+      memmove(&buffer_[0], &buffer_[0] + begin_offset_, size());
+      end_offset_ = length;
+      begin_offset_ = 0;
+    }
+  }
+
+  // Return the maximum size for data in the buffer.
+  size_type capacity() const
+  {
+    return buffer_.size();
+  }
+
+  // Consume multiple bytes from the beginning of the buffer.
+  void consume(size_type count)
+  {
+    BOOST_ASIO_ASSERT(begin_offset_ + count <= end_offset_);
+    begin_offset_ += count;
+    if (empty())
+      clear();
+  }
+
+private:
+  // The offset to the beginning of the unread data.
+  size_type begin_offset_;
+
+  // The offset to the end of the unread data.
+  size_type end_offset_;
+  
+  // The data in the buffer.
+  std::vector<byte_type> buffer_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BUFFERED_STREAM_STORAGE_HPP

+ 127 - 0
cpir-read/boost/boost/asio/detail/call_stack.hpp

@@ -0,0 +1,127 @@
+//
+// detail/call_stack.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CALL_STACK_HPP
+#define BOOST_ASIO_DETAIL_CALL_STACK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/tss_ptr.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Helper class to determine whether or not the current thread is inside an
+// invocation of io_context::run() for a specified io_context object.
+template <typename Key, typename Value = unsigned char>
+class call_stack
+{
+public:
+  // Context class automatically pushes the key/value pair on to the stack.
+  class context
+    : private noncopyable
+  {
+  public:
+    // Push the key on to the stack.
+    explicit context(Key* k)
+      : key_(k),
+        next_(call_stack<Key, Value>::top_)
+    {
+      value_ = reinterpret_cast<unsigned char*>(this);
+      call_stack<Key, Value>::top_ = this;
+    }
+
+    // Push the key/value pair on to the stack.
+    context(Key* k, Value& v)
+      : key_(k),
+        value_(&v),
+        next_(call_stack<Key, Value>::top_)
+    {
+      call_stack<Key, Value>::top_ = this;
+    }
+
+    // Pop the key/value pair from the stack.
+    ~context()
+    {
+      call_stack<Key, Value>::top_ = next_;
+    }
+
+    // Find the next context with the same key.
+    Value* next_by_key() const
+    {
+      context* elem = next_;
+      while (elem)
+      {
+        if (elem->key_ == key_)
+          return elem->value_;
+        elem = elem->next_;
+      }
+      return 0;
+    }
+
+  private:
+    friend class call_stack<Key, Value>;
+
+    // The key associated with the context.
+    Key* key_;
+
+    // The value associated with the context.
+    Value* value_;
+
+    // The next element in the stack.
+    context* next_;
+  };
+
+  friend class context;
+
+  // Determine whether the specified owner is on the stack. Returns address of
+  // key if present, 0 otherwise.
+  static Value* contains(Key* k)
+  {
+    context* elem = top_;
+    while (elem)
+    {
+      if (elem->key_ == k)
+        return elem->value_;
+      elem = elem->next_;
+    }
+    return 0;
+  }
+
+  // Obtain the value at the top of the stack.
+  static Value* top()
+  {
+    context* elem = top_;
+    return elem ? elem->value_ : 0;
+  }
+
+private:
+  // The top of the stack of calls for the current thread.
+  static tss_ptr<context> top_;
+};
+
+template <typename Key, typename Value>
+tss_ptr<typename call_stack<Key, Value>::context>
+call_stack<Key, Value>::top_;
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_CALL_STACK_HPP

+ 68 - 0
cpir-read/boost/boost/asio/detail/chrono.hpp

@@ -0,0 +1,68 @@
+//
+// detail/chrono.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CHRONO_HPP
+#define BOOST_ASIO_DETAIL_CHRONO_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_STD_CHRONO)
+# include <chrono>
+#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+# include <boost/chrono/system_clocks.hpp>
+#endif // defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+
+namespace boost {
+namespace asio {
+namespace chrono {
+
+#if defined(BOOST_ASIO_HAS_STD_CHRONO)
+using std::chrono::duration;
+using std::chrono::time_point;
+using std::chrono::duration_cast;
+using std::chrono::nanoseconds;
+using std::chrono::microseconds;
+using std::chrono::milliseconds;
+using std::chrono::seconds;
+using std::chrono::minutes;
+using std::chrono::hours;
+using std::chrono::time_point_cast;
+#if defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
+typedef std::chrono::monotonic_clock steady_clock;
+#else // defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
+using std::chrono::steady_clock;
+#endif // defined(BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
+using std::chrono::system_clock;
+using std::chrono::high_resolution_clock;
+#elif defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+using boost::chrono::duration;
+using boost::chrono::time_point;
+using boost::chrono::duration_cast;
+using boost::chrono::nanoseconds;
+using boost::chrono::microseconds;
+using boost::chrono::milliseconds;
+using boost::chrono::seconds;
+using boost::chrono::minutes;
+using boost::chrono::hours;
+using boost::chrono::time_point_cast;
+using boost::chrono::system_clock;
+using boost::chrono::steady_clock;
+using boost::chrono::high_resolution_clock;
+#endif // defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+
+} // namespace chrono
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_CHRONO_HPP

+ 192 - 0
cpir-read/boost/boost/asio/detail/chrono_time_traits.hpp

@@ -0,0 +1,192 @@
+//
+// detail/chrono_time_traits.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
+#define BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/cstdint.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Helper template to compute the greatest common divisor.
+template <int64_t v1, int64_t v2>
+struct gcd { enum { value = gcd<v2, v1 % v2>::value }; };
+
+template <int64_t v1>
+struct gcd<v1, 0> { enum { value = v1 }; };
+
+// Adapts std::chrono clocks for use with a deadline timer.
+template <typename Clock, typename WaitTraits>
+struct chrono_time_traits
+{
+  // The clock type.
+  typedef Clock clock_type;
+
+  // The duration type of the clock.
+  typedef typename clock_type::duration duration_type;
+
+  // The time point type of the clock.
+  typedef typename clock_type::time_point time_type;
+
+  // The period of the clock.
+  typedef typename duration_type::period period_type;
+
+  // Get the current time.
+  static time_type now()
+  {
+    return clock_type::now();
+  }
+
+  // Add a duration to a time.
+  static time_type add(const time_type& t, const duration_type& d)
+  {
+    const time_type epoch;
+    if (t >= epoch)
+    {
+      if ((time_type::max)() - t < d)
+        return (time_type::max)();
+    }
+    else // t < epoch
+    {
+      if (-(t - (time_type::min)()) > d)
+        return (time_type::min)();
+    }
+
+    return t + d;
+  }
+
+  // Subtract one time from another.
+  static duration_type subtract(const time_type& t1, const time_type& t2)
+  {
+    const time_type epoch;
+    if (t1 >= epoch)
+    {
+      if (t2 >= epoch)
+      {
+        return t1 - t2;
+      }
+      else if (t2 == (time_type::min)())
+      {
+        return (duration_type::max)();
+      }
+      else if ((time_type::max)() - t1 < epoch - t2)
+      {
+        return (duration_type::max)();
+      }
+      else
+      {
+        return t1 - t2;
+      }
+    }
+    else // t1 < epoch
+    {
+      if (t2 < epoch)
+      {
+        return t1 - t2;
+      }
+      else if (t1 == (time_type::min)())
+      {
+        return (duration_type::min)();
+      }
+      else if ((time_type::max)() - t2 < epoch - t1)
+      {
+        return (duration_type::min)();
+      }
+      else
+      {
+        return -(t2 - t1);
+      }
+    }
+  }
+
+  // Test whether one time is less than another.
+  static bool less_than(const time_type& t1, const time_type& t2)
+  {
+    return t1 < t2;
+  }
+
+  // Implement just enough of the posix_time::time_duration interface to supply
+  // what the timer_queue requires.
+  class posix_time_duration
+  {
+  public:
+    explicit posix_time_duration(const duration_type& d)
+      : d_(d)
+    {
+    }
+
+    int64_t ticks() const
+    {
+      return d_.count();
+    }
+
+    int64_t total_seconds() const
+    {
+      return duration_cast<1, 1>();
+    }
+
+    int64_t total_milliseconds() const
+    {
+      return duration_cast<1, 1000>();
+    }
+
+    int64_t total_microseconds() const
+    {
+      return duration_cast<1, 1000000>();
+    }
+
+  private:
+    template <int64_t Num, int64_t Den>
+    int64_t duration_cast() const
+    {
+      const int64_t num1 = period_type::num / gcd<period_type::num, Num>::value;
+      const int64_t num2 = Num / gcd<period_type::num, Num>::value;
+
+      const int64_t den1 = period_type::den / gcd<period_type::den, Den>::value;
+      const int64_t den2 = Den / gcd<period_type::den, Den>::value;
+
+      const int64_t num = num1 * den2;
+      const int64_t den = num2 * den1;
+
+      if (num == 1 && den == 1)
+        return ticks();
+      else if (num != 1 && den == 1)
+        return ticks() * num;
+      else if (num == 1 && period_type::den != 1)
+        return ticks() / den;
+      else
+        return ticks() * num / den;
+    }
+
+    duration_type d_;
+  };
+
+  // Convert to POSIX duration type.
+  static posix_time_duration to_posix_duration(const duration_type& d)
+  {
+    return posix_time_duration(WaitTraits::to_wait_duration(d));
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_CHRONO_TIME_TRAITS_HPP

+ 85 - 0
cpir-read/boost/boost/asio/detail/completion_handler.hpp

@@ -0,0 +1,85 @@
+//
+// detail/completion_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_COMPLETION_HANDLER_HPP
+#define BOOST_ASIO_DETAIL_COMPLETION_HANDLER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class completion_handler : public operation
+{
+public:
+  BOOST_ASIO_DEFINE_HANDLER_PTR(completion_handler);
+
+  completion_handler(Handler& h)
+    : operation(&completion_handler::do_complete),
+      handler_(BOOST_ASIO_MOVE_CAST(Handler)(h))
+  {
+    handler_work<Handler>::start(handler_);
+  }
+
+  static void do_complete(void* owner, operation* base,
+      const boost::system::error_code& /*ec*/,
+      std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    completion_handler* h(static_cast<completion_handler*>(base));
+    ptr p = { boost::asio::detail::addressof(h->handler_), h, h };
+    handler_work<Handler> w(h->handler_);
+
+    BOOST_ASIO_HANDLER_COMPLETION((*h));
+
+    // Make a copy of the handler so that the memory can be deallocated before
+    // the upcall is made. Even if we're not about to make an upcall, a
+    // sub-object of the handler may be the true owner of the memory associated
+    // with the handler. Consequently, a local copy of the handler is required
+    // to ensure that any owning sub-object remains valid until after we have
+    // deallocated the memory here.
+    Handler handler(BOOST_ASIO_MOVE_CAST(Handler)(h->handler_));
+    p.h = boost::asio::detail::addressof(handler);
+    p.reset();
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      fenced_block b(fenced_block::half);
+      BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
+      w.complete(handler, handler);
+      BOOST_ASIO_HANDLER_INVOCATION_END;
+    }
+  }
+
+private:
+  Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_COMPLETION_HANDLER_HPP

+ 94 - 0
cpir-read/boost/boost/asio/detail/concurrency_hint.hpp

@@ -0,0 +1,94 @@
+//
+// detail/concurrency_hint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CONCURRENCY_HINT_HPP
+#define BOOST_ASIO_DETAIL_CONCURRENCY_HINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+
+// The concurrency hint ID and mask are used to identify when a "well-known"
+// concurrency hint value has been passed to the io_context.
+#define BOOST_ASIO_CONCURRENCY_HINT_ID 0xA5100000u
+#define BOOST_ASIO_CONCURRENCY_HINT_ID_MASK 0xFFFF0000u
+
+// If set, this bit indicates that the scheduler should perform locking.
+#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER 0x1u
+
+// If set, this bit indicates that the reactor should perform locking when
+// managing descriptor registrations.
+#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION 0x2u
+
+// If set, this bit indicates that the reactor should perform locking for I/O.
+#define BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO 0x4u
+
+// Helper macro to determine if we have a special concurrency hint.
+#define BOOST_ASIO_CONCURRENCY_HINT_IS_SPECIAL(hint) \
+  ((static_cast<unsigned>(hint) \
+    & BOOST_ASIO_CONCURRENCY_HINT_ID_MASK) \
+      == BOOST_ASIO_CONCURRENCY_HINT_ID)
+
+// Helper macro to determine if locking is enabled for a given facility.
+#define BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(facility, hint) \
+  (((static_cast<unsigned>(hint) \
+    & (BOOST_ASIO_CONCURRENCY_HINT_ID_MASK \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_ ## facility)) \
+        ^ BOOST_ASIO_CONCURRENCY_HINT_ID) != 0)
+
+// This special concurrency hint disables locking in both the scheduler and
+// reactor I/O. This hint has the following restrictions:
+//
+// - Care must be taken to ensure that all operations on the io_context and any
+//   of its associated I/O objects (such as sockets and timers) occur in only
+//   one thread at a time.
+//
+// - Asynchronous resolve operations fail with operation_not_supported.
+//
+// - If a signal_set is used with the io_context, signal_set objects cannot be
+//   used with any other io_context in the program.
+#define BOOST_ASIO_CONCURRENCY_HINT_UNSAFE \
+  static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID)
+
+// This special concurrency hint disables locking in the reactor I/O. This hint
+// has the following restrictions:
+//
+// - Care must be taken to ensure that run functions on the io_context, and all
+//   operations on the io_context's associated I/O objects (such as sockets and
+//   timers), occur in only one thread at a time.
+#define BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO \
+  static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION)
+
+// The special concurrency hint provides full thread safety.
+#define BOOST_ASIO_CONCURRENCY_HINT_SAFE \
+  static_cast<int>(BOOST_ASIO_CONCURRENCY_HINT_ID \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION \
+      | BOOST_ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO)
+
+// This #define may be overridden at compile time to specify a program-wide
+// default concurrency hint, used by the zero-argument io_context constructor.
+#if !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
+# define BOOST_ASIO_CONCURRENCY_HINT_DEFAULT -1
+#endif // !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
+
+// This #define may be overridden at compile time to specify a program-wide
+// concurrency hint, used by the one-argument io_context constructor when
+// passed a value of 1.
+#if !defined(BOOST_ASIO_CONCURRENCY_HINT_1)
+# define BOOST_ASIO_CONCURRENCY_HINT_1 1
+#endif // !defined(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
+
+#endif // BOOST_ASIO_DETAIL_CONCURRENCY_HINT_HPP

+ 114 - 0
cpir-read/boost/boost/asio/detail/conditionally_enabled_event.hpp

@@ -0,0 +1,114 @@
+//
+// detail/conditionally_enabled_event.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
+#define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/conditionally_enabled_mutex.hpp>
+#include <boost/asio/detail/event.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/null_event.hpp>
+#include <boost/asio/detail/scoped_lock.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Mutex adapter used to conditionally enable or disable locking.
+class conditionally_enabled_event
+  : private noncopyable
+{
+public:
+  // Constructor.
+  conditionally_enabled_event()
+  {
+  }
+
+  // Destructor.
+  ~conditionally_enabled_event()
+  {
+  }
+
+  // Signal the event. (Retained for backward compatibility.)
+  void signal(conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      event_.signal(lock);
+  }
+
+  // Signal all waiters.
+  void signal_all(conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      event_.signal_all(lock);
+  }
+
+  // Unlock the mutex and signal one waiter.
+  void unlock_and_signal_one(
+      conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      event_.unlock_and_signal_one(lock);
+  }
+
+  // If there's a waiter, unlock the mutex and signal it.
+  bool maybe_unlock_and_signal_one(
+      conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      return event_.maybe_unlock_and_signal_one(lock);
+    else
+      return false;
+  }
+
+  // Reset the event.
+  void clear(conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      event_.clear(lock);
+  }
+
+  // Wait for the event to become signalled.
+  void wait(conditionally_enabled_mutex::scoped_lock& lock)
+  {
+    if (lock.mutex_.enabled_)
+      event_.wait(lock);
+    else
+      null_event().wait(lock);
+  }
+
+  // Timed wait for the event to become signalled.
+  bool wait_for_usec(
+      conditionally_enabled_mutex::scoped_lock& lock, long usec)
+  {
+    if (lock.mutex_.enabled_)
+      return event_.wait_for_usec(lock, usec);
+    else
+      return null_event().wait_for_usec(lock, usec);
+  }
+
+private:
+  boost::asio::detail::event event_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP

+ 151 - 0
cpir-read/boost/boost/asio/detail/conditionally_enabled_mutex.hpp

@@ -0,0 +1,151 @@
+//
+// detail/conditionally_enabled_mutex.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
+#define BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/scoped_lock.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Mutex adapter used to conditionally enable or disable locking.
+class conditionally_enabled_mutex
+  : private noncopyable
+{
+public:
+  // Helper class to lock and unlock a mutex automatically.
+  class scoped_lock
+    : private noncopyable
+  {
+  public:
+    // Tag type used to distinguish constructors.
+    enum adopt_lock_t { adopt_lock };
+
+    // Constructor adopts a lock that is already held.
+    scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t)
+      : mutex_(m),
+        locked_(m.enabled_)
+    {
+    }
+
+    // Constructor acquires the lock.
+    explicit scoped_lock(conditionally_enabled_mutex& m)
+      : mutex_(m)
+    {
+      if (m.enabled_)
+      {
+        mutex_.mutex_.lock();
+        locked_ = true;
+      }
+      else
+        locked_ = false;
+    }
+
+    // Destructor releases the lock.
+    ~scoped_lock()
+    {
+      if (locked_)
+        mutex_.mutex_.unlock();
+    }
+
+    // Explicitly acquire the lock.
+    void lock()
+    {
+      if (mutex_.enabled_ && !locked_)
+      {
+        mutex_.mutex_.lock();
+        locked_ = true;
+      }
+    }
+
+    // Explicitly release the lock.
+    void unlock()
+    {
+      if (locked_)
+      {
+        mutex_.unlock();
+        locked_ = false;
+      }
+    }
+
+    // Test whether the lock is held.
+    bool locked() const
+    {
+      return locked_;
+    }
+
+    // Get the underlying mutex.
+    boost::asio::detail::mutex& mutex()
+    {
+      return mutex_.mutex_;
+    }
+
+  private:
+    friend class conditionally_enabled_event;
+    conditionally_enabled_mutex& mutex_;
+    bool locked_;
+  };
+
+  // Constructor.
+  explicit conditionally_enabled_mutex(bool enabled)
+    : enabled_(enabled)
+  {
+  }
+
+  // Destructor.
+  ~conditionally_enabled_mutex()
+  {
+  }
+
+  // Determine whether locking is enabled.
+  bool enabled() const
+  {
+    return enabled_;
+  }
+
+  // Lock the mutex.
+  void lock()
+  {
+    if (enabled_)
+      mutex_.lock();
+  }
+
+  // Unlock the mutex.
+  void unlock()
+  {
+    if (enabled_)
+      mutex_.unlock();
+  }
+
+private:
+  friend class scoped_lock;
+  friend class conditionally_enabled_event;
+  boost::asio::detail::mutex mutex_;
+  const bool enabled_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP

+ 1435 - 0
cpir-read/boost/boost/asio/detail/config.hpp

@@ -0,0 +1,1435 @@
+//
+// detail/config.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CONFIG_HPP
+#define BOOST_ASIO_DETAIL_CONFIG_HPP
+
+#if defined(BOOST_ASIO_STANDALONE)
+# define BOOST_ASIO_DISABLE_BOOST_ARRAY 1
+# define BOOST_ASIO_DISABLE_BOOST_ASSERT 1
+# define BOOST_ASIO_DISABLE_BOOST_BIND 1
+# define BOOST_ASIO_DISABLE_BOOST_CHRONO 1
+# define BOOST_ASIO_DISABLE_BOOST_DATE_TIME 1
+# define BOOST_ASIO_DISABLE_BOOST_LIMITS 1
+# define BOOST_ASIO_DISABLE_BOOST_REGEX 1
+# define BOOST_ASIO_DISABLE_BOOST_STATIC_CONSTANT 1
+# define BOOST_ASIO_DISABLE_BOOST_THROW_EXCEPTION 1
+# define BOOST_ASIO_DISABLE_BOOST_WORKAROUND 1
+#else // defined(BOOST_ASIO_STANDALONE)
+# include <boost/config.hpp>
+# include <boost/version.hpp>
+# define BOOST_ASIO_HAS_BOOST_CONFIG 1
+#endif // defined(BOOST_ASIO_STANDALONE)
+
+// Default to a header-only implementation. The user must specifically request
+// separate compilation by defining either BOOST_ASIO_SEPARATE_COMPILATION or
+// BOOST_ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).
+#if !defined(BOOST_ASIO_HEADER_ONLY)
+# if !defined(BOOST_ASIO_SEPARATE_COMPILATION)
+#  if !defined(BOOST_ASIO_DYN_LINK)
+#   define BOOST_ASIO_HEADER_ONLY 1
+#  endif // !defined(BOOST_ASIO_DYN_LINK)
+# endif // !defined(BOOST_ASIO_SEPARATE_COMPILATION)
+#endif // !defined(BOOST_ASIO_HEADER_ONLY)
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# define BOOST_ASIO_DECL inline
+#else // defined(BOOST_ASIO_HEADER_ONLY)
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)
+// We need to import/export our code only if the user has specifically asked
+// for it by defining BOOST_ASIO_DYN_LINK.
+#  if defined(BOOST_ASIO_DYN_LINK)
+// Export if this is our own source, otherwise import.
+#   if defined(BOOST_ASIO_SOURCE)
+#    define BOOST_ASIO_DECL __declspec(dllexport)
+#   else // defined(BOOST_ASIO_SOURCE)
+#    define BOOST_ASIO_DECL __declspec(dllimport)
+#   endif // defined(BOOST_ASIO_SOURCE)
+#  endif // defined(BOOST_ASIO_DYN_LINK)
+# endif // defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CODEGEARC__)
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+// If BOOST_ASIO_DECL isn't defined yet define it now.
+#if !defined(BOOST_ASIO_DECL)
+# define BOOST_ASIO_DECL
+#endif // !defined(BOOST_ASIO_DECL)
+
+// Microsoft Visual C++ detection.
+#if !defined(BOOST_ASIO_MSVC)
+# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
+#  define BOOST_ASIO_MSVC BOOST_MSVC
+# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \
+      || (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))
+#  define BOOST_ASIO_MSVC _MSC_VER
+# endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
+#endif // !defined(BOOST_ASIO_MSVC)
+#if defined(BOOST_ASIO_MSVC)
+# include <ciso646> // Needed for _HAS_CXX17.
+#endif // defined(BOOST_ASIO_MSVC)
+
+// Clang / libc++ detection.
+#if defined(__clang__)
+# if (__cplusplus >= 201103)
+#  if __has_include(<__config>)
+#   include <__config>
+#   if defined(_LIBCPP_VERSION)
+#    define BOOST_ASIO_HAS_CLANG_LIBCXX 1
+#   endif // defined(_LIBCPP_VERSION)
+#  endif // __has_include(<__config>)
+# endif // (__cplusplus >= 201103)
+#endif // defined(__clang__)
+
+// Android platform detection.
+#if defined(__ANDROID__)
+# include <android/api-level.h>
+#endif // defined(__ANDROID__)
+
+// Support move construction and assignment on compilers known to allow it.
+#if !defined(BOOST_ASIO_HAS_MOVE)
+# if !defined(BOOST_ASIO_DISABLE_MOVE)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_rvalue_references__)
+#    define BOOST_ASIO_HAS_MOVE 1
+#   endif // __has_feature(__cxx_rvalue_references__)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_MOVE 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_MOVE 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_MOVE)
+#endif // !defined(BOOST_ASIO_HAS_MOVE)
+
+// If BOOST_ASIO_MOVE_CAST isn't defined, and move support is available, define
+// BOOST_ASIO_MOVE_ARG and BOOST_ASIO_MOVE_CAST to take advantage of rvalue
+// references and perfect forwarding.
+#if defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
+# define BOOST_ASIO_MOVE_ARG(type) type&&
+# define BOOST_ASIO_MOVE_ARG2(type1, type2) type1, type2&&
+# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
+# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
+#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
+
+// If BOOST_ASIO_MOVE_CAST still isn't defined, default to a C++03-compatible
+// implementation. Note that older g++ and MSVC versions don't like it when you
+// pass a non-member function through a const reference, so for most compilers
+// we'll play it safe and stick with the old approach of passing the handler by
+// value.
+#if !defined(BOOST_ASIO_MOVE_CAST)
+# if defined(__GNUC__)
+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)
+#   define BOOST_ASIO_MOVE_ARG(type) const type&
+#  else // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)
+#   define BOOST_ASIO_MOVE_ARG(type) type
+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) || (__GNUC__ > 4)
+# elif defined(BOOST_ASIO_MSVC)
+#  if (_MSC_VER >= 1400)
+#   define BOOST_ASIO_MOVE_ARG(type) const type&
+#  else // (_MSC_VER >= 1400)
+#   define BOOST_ASIO_MOVE_ARG(type) type
+#  endif // (_MSC_VER >= 1400)
+# else
+#  define BOOST_ASIO_MOVE_ARG(type) type
+# endif
+# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
+# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
+#endif // !defined(BOOST_ASIO_MOVE_CAST)
+
+// Support variadic templates on compilers known to allow it.
+#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+# if !defined(BOOST_ASIO_DISABLE_VARIADIC_TEMPLATES)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_variadic_templates__)
+#    define BOOST_ASIO_HAS_VARIADIC_TEMPLATES 1
+#   endif // __has_feature(__cxx_variadic_templates__)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_VARIADIC_TEMPLATES 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1900)
+#    define BOOST_ASIO_HAS_VARIADIC_TEMPLATES 1
+#   endif // (_MSC_VER >= 1900)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_VARIADIC_TEMPLATES)
+#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+// Support deleted functions on compilers known to allow it.
+#if !defined(BOOST_ASIO_DELETED)
+# if defined(__GNUC__)
+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#   if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#    define BOOST_ASIO_DELETED = delete
+#   endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+# endif // defined(__GNUC__)
+# if defined(__clang__)
+#  if __has_feature(__cxx_deleted_functions__)
+#   define BOOST_ASIO_DELETED = delete
+#  endif // __has_feature(__cxx_deleted_functions__)
+# endif // defined(__clang__)
+# if defined(BOOST_ASIO_MSVC)
+#  if (_MSC_VER >= 1900)
+#   define BOOST_ASIO_DELETED = delete
+#  endif // (_MSC_VER >= 1900)
+# endif // defined(BOOST_ASIO_MSVC)
+# if !defined(BOOST_ASIO_DELETED)
+#  define BOOST_ASIO_DELETED
+# endif // !defined(BOOST_ASIO_DELETED)
+#endif // !defined(BOOST_ASIO_DELETED)
+
+// Support constexpr on compilers known to allow it.
+#if !defined(BOOST_ASIO_HAS_CONSTEXPR)
+# if !defined(BOOST_ASIO_DISABLE_CONSTEXPR)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_constexpr__)
+#    define BOOST_ASIO_HAS_CONSTEXPR 1
+#   endif // __has_feature(__cxx_constexr__)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_CONSTEXPR 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1900)
+#    define BOOST_ASIO_HAS_CONSTEXPR 1
+#   endif // (_MSC_VER >= 1900)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_CONSTEXPR)
+#endif // !defined(BOOST_ASIO_HAS_CONSTEXPR)
+#if !defined(BOOST_ASIO_CONSTEXPR)
+# if defined(BOOST_ASIO_HAS_CONSTEXPR)
+#  define BOOST_ASIO_CONSTEXPR constexpr
+# else // defined(BOOST_ASIO_HAS_CONSTEXPR)
+#  define BOOST_ASIO_CONSTEXPR
+# endif // defined(BOOST_ASIO_HAS_CONSTEXPR)
+#endif // !defined(BOOST_ASIO_CONSTEXPR)
+
+// Support noexcept on compilers known to allow it.
+#if !defined(BOOST_ASIO_NOEXCEPT)
+# if !defined(BOOST_ASIO_DISABLE_NOEXCEPT)
+#  if (BOOST_VERSION >= 105300)
+#   define BOOST_ASIO_NOEXCEPT BOOST_NOEXCEPT
+#   define BOOST_ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW
+#  elif defined(__clang__)
+#   if __has_feature(__cxx_noexcept__)
+#    define BOOST_ASIO_NOEXCEPT noexcept(true)
+#    define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
+#   endif // __has_feature(__cxx_noexcept__)
+#  elif defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#      define BOOST_ASIO_NOEXCEPT noexcept(true)
+#      define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  elif defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1900)
+#    define BOOST_ASIO_NOEXCEPT noexcept(true)
+#    define BOOST_ASIO_NOEXCEPT_OR_NOTHROW noexcept(true)
+#   endif // (_MSC_VER >= 1900)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_NOEXCEPT)
+# if !defined(BOOST_ASIO_NOEXCEPT)
+#  define BOOST_ASIO_NOEXCEPT
+# endif // !defined(BOOST_ASIO_NOEXCEPT)
+# if !defined(BOOST_ASIO_NOEXCEPT_OR_NOTHROW)
+#  define BOOST_ASIO_NOEXCEPT_OR_NOTHROW throw()
+# endif // !defined(BOOST_ASIO_NOEXCEPT_OR_NOTHROW)
+#endif // !defined(BOOST_ASIO_NOEXCEPT)
+
+// Support automatic type deduction on compilers known to support it.
+#if !defined(BOOST_ASIO_HAS_DECLTYPE)
+# if !defined(BOOST_ASIO_DISABLE_DECLTYPE)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_decltype__)
+#    define BOOST_ASIO_HAS_DECLTYPE 1
+#   endif // __has_feature(__cxx_decltype__)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_DECLTYPE 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_DECLTYPE 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
+#endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
+
+// Support alias templates on compilers known to allow it.
+#if !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+# if !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_alias_templates__)
+#    define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
+#   endif // __has_feature(__cxx_alias_templates__)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1900)
+#    define BOOST_ASIO_HAS_ALIAS_TEMPLATES 1
+#   endif // (_MSC_VER >= 1900)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_ALIAS_TEMPLATES)
+#endif // !defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+// Standard library support for system errors.
+# if !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_SYSTEM_ERROR 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<system_error>)
+#     define BOOST_ASIO_HAS_STD_SYSTEM_ERROR 1
+#    endif // __has_include(<system_error>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_SYSTEM_ERROR 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_SYSTEM_ERROR 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_SYSTEM_ERROR)
+
+// Compliant C++11 compilers put noexcept specifiers on error_category members.
+#if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
+# if (BOOST_VERSION >= 105300)
+#  define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT BOOST_NOEXCEPT
+# elif defined(__clang__)
+#  if __has_feature(__cxx_noexcept__)
+#   define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
+#  endif // __has_feature(__cxx_noexcept__)
+# elif defined(__GNUC__)
+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#   if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
+#   endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+# elif defined(BOOST_ASIO_MSVC)
+#  if (_MSC_VER >= 1900)
+#   define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
+#  endif // (_MSC_VER >= 1900)
+# endif // defined(BOOST_ASIO_MSVC)
+# if !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
+#  define BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT
+# endif // !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
+#endif // !defined(BOOST_ASIO_ERROR_CATEGORY_NOEXCEPT)
+
+// Standard library support for arrays.
+#if !defined(BOOST_ASIO_HAS_STD_ARRAY)
+# if !defined(BOOST_ASIO_DISABLE_STD_ARRAY)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_ARRAY 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<array>)
+#     define BOOST_ASIO_HAS_STD_ARRAY 1
+#    endif // __has_include(<array>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_ARRAY 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1600)
+#    define BOOST_ASIO_HAS_STD_ARRAY 1
+#   endif // (_MSC_VER >= 1600)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_ARRAY)
+#endif // !defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+// Standard library support for shared_ptr and weak_ptr.
+#if !defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
+# if !defined(BOOST_ASIO_DISABLE_STD_SHARED_PTR)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_SHARED_PTR 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_STD_SHARED_PTR 1
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_SHARED_PTR 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1600)
+#    define BOOST_ASIO_HAS_STD_SHARED_PTR 1
+#   endif // (_MSC_VER >= 1600)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_SHARED_PTR)
+#endif // !defined(BOOST_ASIO_HAS_STD_SHARED_PTR)
+
+// Standard library support for allocator_arg_t.
+#if !defined(BOOST_ASIO_HAS_STD_ALLOCATOR_ARG)
+# if !defined(BOOST_ASIO_DISABLE_STD_ALLOCATOR_ARG)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1600)
+#    define BOOST_ASIO_HAS_STD_ALLOCATOR_ARG 1
+#   endif // (_MSC_VER >= 1600)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_ALLOCATOR_ARG)
+#endif // !defined(BOOST_ASIO_HAS_STD_ALLOCATOR_ARG)
+
+// Standard library support for atomic operations.
+#if !defined(BOOST_ASIO_HAS_STD_ATOMIC)
+# if !defined(BOOST_ASIO_DISABLE_STD_ATOMIC)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_ATOMIC 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<atomic>)
+#     define BOOST_ASIO_HAS_STD_ATOMIC 1
+#    endif // __has_include(<atomic>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_ATOMIC 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_ATOMIC 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_ATOMIC)
+#endif // !defined(BOOST_ASIO_HAS_STD_ATOMIC)
+
+// Standard library support for chrono. Some standard libraries (such as the
+// libstdc++ shipped with gcc 4.6) provide monotonic_clock as per early C++0x
+// drafts, rather than the eventually standardised name of steady_clock.
+#if !defined(BOOST_ASIO_HAS_STD_CHRONO)
+# if !defined(BOOST_ASIO_DISABLE_STD_CHRONO)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_CHRONO 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<chrono>)
+#     define BOOST_ASIO_HAS_STD_CHRONO 1
+#    endif // __has_include(<chrono>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_CHRONO 1
+#     if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))
+#      define BOOST_ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK 1
+#     endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6))
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_CHRONO 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_CHRONO)
+#endif // !defined(BOOST_ASIO_HAS_STD_CHRONO)
+
+// Boost support for chrono.
+#if !defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
+#  if (BOOST_VERSION >= 104700)
+#   define BOOST_ASIO_HAS_BOOST_CHRONO 1
+#  endif // (BOOST_VERSION >= 104700)
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_CHRONO)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+
+// Some form of chrono library is available.
+#if !defined(BOOST_ASIO_HAS_CHRONO)
+# if defined(BOOST_ASIO_HAS_STD_CHRONO) \
+    || defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+#  define BOOST_ASIO_HAS_CHRONO 1
+# endif // defined(BOOST_ASIO_HAS_STD_CHRONO)
+        // || defined(BOOST_ASIO_HAS_BOOST_CHRONO)
+#endif // !defined(BOOST_ASIO_HAS_CHRONO)
+
+// Boost support for the DateTime library.
+#if !defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_DATE_TIME)
+#  define BOOST_ASIO_HAS_BOOST_DATE_TIME 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_DATE_TIME)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+
+// Standard library support for addressof.
+#if !defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
+# if !defined(BOOST_ASIO_DISABLE_STD_ADDRESSOF)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_ADDRESSOF 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_STD_ADDRESSOF 1
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_ADDRESSOF 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_ADDRESSOF 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_ADDRESSOF)
+#endif // !defined(BOOST_ASIO_HAS_STD_ADDRESSOF)
+
+// Standard library support for the function class.
+#if !defined(BOOST_ASIO_HAS_STD_FUNCTION)
+# if !defined(BOOST_ASIO_DISABLE_STD_FUNCTION)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_FUNCTION 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_STD_FUNCTION 1
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_FUNCTION 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_FUNCTION 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_FUNCTION)
+#endif // !defined(BOOST_ASIO_HAS_STD_FUNCTION)
+
+// Standard library support for type traits.
+#if !defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS)
+# if !defined(BOOST_ASIO_DISABLE_STD_TYPE_TRAITS)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_TYPE_TRAITS 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<type_traits>)
+#     define BOOST_ASIO_HAS_STD_TYPE_TRAITS 1
+#    endif // __has_include(<type_traits>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_TYPE_TRAITS 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_TYPE_TRAITS 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_TYPE_TRAITS)
+#endif // !defined(BOOST_ASIO_HAS_STD_TYPE_TRAITS)
+
+// Standard library support for the nullptr_t type.
+#if !defined(BOOST_ASIO_HAS_NULLPTR)
+# if !defined(BOOST_ASIO_DISABLE_NULLPTR)
+#  if defined(__clang__)
+#   if __has_feature(__cxx_nullptr__)
+#    define BOOST_ASIO_HAS_NULLPTR 1
+#   endif // __has_feature(__cxx_rvalue_references__)
+#  elif defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_NULLPTR 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_NULLPTR 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_NULLPTR)
+#endif // !defined(BOOST_ASIO_HAS_NULLPTR)
+
+// Standard library support for the C++11 allocator additions.
+#if !defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
+# if !defined(BOOST_ASIO_DISABLE_CXX11_ALLOCATORS)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
+#   endif // (__cplusplus >= 201103)
+#  elif defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1800)
+#    define BOOST_ASIO_HAS_CXX11_ALLOCATORS 1
+#   endif // (_MSC_VER >= 1800)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_CXX11_ALLOCATORS)
+#endif // !defined(BOOST_ASIO_HAS_CXX11_ALLOCATORS)
+
+// Standard library support for the cstdint header.
+#if !defined(BOOST_ASIO_HAS_CSTDINT)
+# if !defined(BOOST_ASIO_DISABLE_CSTDINT)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_CSTDINT 1
+#   elif (__cplusplus >= 201103)
+#    define BOOST_ASIO_HAS_CSTDINT 1
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_CSTDINT 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_CSTDINT 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_CSTDINT)
+#endif // !defined(BOOST_ASIO_HAS_CSTDINT)
+
+// Standard library support for the thread class.
+#if !defined(BOOST_ASIO_HAS_STD_THREAD)
+# if !defined(BOOST_ASIO_DISABLE_STD_THREAD)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_THREAD 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<thread>)
+#     define BOOST_ASIO_HAS_STD_THREAD 1
+#    endif // __has_include(<thread>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_THREAD 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_THREAD 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_THREAD)
+#endif // !defined(BOOST_ASIO_HAS_STD_THREAD)
+
+// Standard library support for the mutex and condition variable classes.
+#if !defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
+# if !defined(BOOST_ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<mutex>)
+#     define BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR 1
+#    endif // __has_include(<mutex>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_MUTEX_AND_CONDVAR)
+#endif // !defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
+
+// Standard library support for the call_once function.
+#if !defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
+# if !defined(BOOST_ASIO_DISABLE_STD_CALL_ONCE)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_CALL_ONCE 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<mutex>)
+#     define BOOST_ASIO_HAS_STD_CALL_ONCE 1
+#    endif // __has_include(<mutex>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_CALL_ONCE 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_CALL_ONCE 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_CALL_ONCE)
+#endif // !defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
+
+// Standard library support for futures.
+#if !defined(BOOST_ASIO_HAS_STD_FUTURE)
+# if !defined(BOOST_ASIO_DISABLE_STD_FUTURE)
+#  if defined(__clang__)
+#   if defined(BOOST_ASIO_HAS_CLANG_LIBCXX)
+#    define BOOST_ASIO_HAS_STD_FUTURE 1
+#   elif (__cplusplus >= 201103)
+#    if __has_include(<future>)
+#     define BOOST_ASIO_HAS_STD_FUTURE 1
+#    endif // __has_include(<mutex>)
+#   endif // (__cplusplus >= 201103)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     if defined(_GLIBCXX_HAS_GTHREADS)
+#      define BOOST_ASIO_HAS_STD_FUTURE 1
+#     endif // defined(_GLIBCXX_HAS_GTHREADS)
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_FUTURE 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_FUTURE)
+#endif // !defined(BOOST_ASIO_HAS_STD_FUTURE)
+
+// Standard library support for std::string_view.
+#if !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
+# if !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
+#  if defined(__clang__)
+#   if (__cplusplus >= 201703)
+#    if __has_include(<string_view>)
+#     define BOOST_ASIO_HAS_STD_STRING_VIEW 1
+#    endif // __has_include(<string_view>)
+#   endif // (__cplusplus >= 201703)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if (__GNUC__ >= 7)
+#    if (__cplusplus >= 201703)
+#     define BOOST_ASIO_HAS_STD_STRING_VIEW 1
+#    endif // (__cplusplus >= 201703)
+#   endif // (__GNUC__ >= 7)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1910 && _HAS_CXX17)
+#    define BOOST_ASIO_HAS_STD_STRING_VIEW
+#   endif // (_MSC_VER >= 1910 && _HAS_CXX17)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_STRING_VIEW)
+#endif // !defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
+
+// Standard library support for std::experimental::string_view.
+#if !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+# if !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
+#  if defined(__clang__)
+#   if (__cplusplus >= 201402)
+#    if __has_include(<experimental/string_view>)
+#     define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
+#    endif // __has_include(<experimental/string_view>)
+#   endif // (__cplusplus >= 201402)
+#  endif // defined(__clang__)
+#  if defined(__GNUC__)
+#   if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
+#    if (__cplusplus >= 201402)
+#     define BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
+#    endif // (__cplusplus >= 201402)
+#   endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
+#endif // !defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+
+// Standard library has a string_view that we can use.
+#if !defined(BOOST_ASIO_HAS_STRING_VIEW)
+# if !defined(BOOST_ASIO_DISABLE_STRING_VIEW)
+#  if defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
+#   define BOOST_ASIO_HAS_STRING_VIEW 1
+#  elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+#   define BOOST_ASIO_HAS_STRING_VIEW 1
+#  endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
+# endif // !defined(BOOST_ASIO_DISABLE_STRING_VIEW)
+#endif // !defined(BOOST_ASIO_HAS_STRING_VIEW)
+
+// Standard library support for iostream move construction and assignment.
+#if !defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
+# if !defined(BOOST_ASIO_DISABLE_STD_IOSTREAM_MOVE)
+#  if defined(__GNUC__)
+#   if (__GNUC__ > 4)
+#    if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#     define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
+#    endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#   endif // (__GNUC__ > 4)
+#  endif // defined(__GNUC__)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1700)
+#    define BOOST_ASIO_HAS_STD_IOSTREAM_MOVE 1
+#   endif // (_MSC_VER >= 1700)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_IOSTREAM_MOVE)
+#endif // !defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
+
+// Standard library has invoke_result (which supersedes result_of).
+#if !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
+# if !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_VER >= 1910 && _HAS_CXX17)
+#    define BOOST_ASIO_HAS_STD_INVOKE_RESULT 1
+#   endif // (_MSC_VER >= 1910 && _HAS_CXX17)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_STD_INVOKE_RESULT)
+#endif // !defined(BOOST_ASIO_HAS_STD_INVOKE_RESULT)
+
+// Windows App target. Windows but with a limited API.
+#if !defined(BOOST_ASIO_WINDOWS_APP)
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
+#  include <winapifamily.h>
+#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \
+   && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#   define BOOST_ASIO_WINDOWS_APP 1
+#  endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+         // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
+#endif // !defined(BOOST_ASIO_WINDOWS_APP)
+
+// Legacy WinRT target. Windows App is preferred.
+#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# if !defined(BOOST_ASIO_WINDOWS_APP)
+#  if defined(__cplusplus_winrt)
+#   include <winapifamily.h>
+#   if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) \
+    && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#    define BOOST_ASIO_WINDOWS_RUNTIME 1
+#   endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+          // && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#  endif // defined(__cplusplus_winrt)
+# endif // !defined(BOOST_ASIO_WINDOWS_APP)
+#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+// Windows target. Excludes WinRT but includes Windows App targets.
+#if !defined(BOOST_ASIO_WINDOWS)
+# if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#  if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)
+#   define BOOST_ASIO_WINDOWS 1
+#  elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+#   define BOOST_ASIO_WINDOWS 1
+#  elif defined(BOOST_ASIO_WINDOWS_APP)
+#   define BOOST_ASIO_WINDOWS 1
+#  endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_WINDOWS)
+# endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#endif // !defined(BOOST_ASIO_WINDOWS)
+
+// Windows: target OS version.
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
+#  if defined(_MSC_VER) || defined(__BORLANDC__)
+#   pragma message( \
+  "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
+  "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
+  "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
+  "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
+#  else // defined(_MSC_VER) || defined(__BORLANDC__)
+#   warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
+#   warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
+#   warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
+#  endif // defined(_MSC_VER) || defined(__BORLANDC__)
+#  define _WIN32_WINNT 0x0501
+# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
+# if defined(_MSC_VER)
+#  if defined(_WIN32) && !defined(WIN32)
+#   if !defined(_WINSOCK2API_)
+#    define WIN32 // Needed for correct types in winsock2.h
+#   else // !defined(_WINSOCK2API_)
+#    error Please define the macro WIN32 in your compiler options
+#   endif // !defined(_WINSOCK2API_)
+#  endif // defined(_WIN32) && !defined(WIN32)
+# endif // defined(_MSC_VER)
+# if defined(__BORLANDC__)
+#  if defined(__WIN32__) && !defined(WIN32)
+#   if !defined(_WINSOCK2API_)
+#    define WIN32 // Needed for correct types in winsock2.h
+#   else // !defined(_WINSOCK2API_)
+#    error Please define the macro WIN32 in your compiler options
+#   endif // !defined(_WINSOCK2API_)
+#  endif // defined(__WIN32__) && !defined(WIN32)
+# endif // defined(__BORLANDC__)
+# if defined(__CYGWIN__)
+#  if !defined(__USE_W32_SOCKETS)
+#   error You must add -D__USE_W32_SOCKETS to your compiler options.
+#  endif // !defined(__USE_W32_SOCKETS)
+# endif // defined(__CYGWIN__)
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: minimise header inclusion.
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
+#  if !defined(WIN32_LEAN_AND_MEAN)
+#   define WIN32_LEAN_AND_MEAN
+#  endif // !defined(WIN32_LEAN_AND_MEAN)
+# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: suppress definition of "min" and "max" macros.
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# if !defined(BOOST_ASIO_NO_NOMINMAX)
+#  if !defined(NOMINMAX)
+#   define NOMINMAX 1
+#  endif // !defined(NOMINMAX)
+# endif // !defined(BOOST_ASIO_NO_NOMINMAX)
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: IO Completion Ports.
+#if !defined(BOOST_ASIO_HAS_IOCP)
+# if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+#  if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+#   if !defined(UNDER_CE) && !defined(BOOST_ASIO_WINDOWS_APP)
+#    if !defined(BOOST_ASIO_DISABLE_IOCP)
+#     define BOOST_ASIO_HAS_IOCP 1
+#    endif // !defined(BOOST_ASIO_DISABLE_IOCP)
+#   endif // !defined(UNDER_CE) && !defined(BOOST_ASIO_WINDOWS_APP)
+#  endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+# endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+// On POSIX (and POSIX-like) platforms we need to include unistd.h in order to
+// get access to the various platform feature macros, e.g. to be able to test
+// for threads support.
+#if !defined(BOOST_ASIO_HAS_UNISTD_H)
+# if !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
+#  if defined(unix) \
+   || defined(__unix) \
+   || defined(_XOPEN_SOURCE) \
+   || defined(_POSIX_SOURCE) \
+   || (defined(__MACH__) && defined(__APPLE__)) \
+   || defined(__FreeBSD__) \
+   || defined(__NetBSD__) \
+   || defined(__OpenBSD__) \
+   || defined(__linux__)
+#   define BOOST_ASIO_HAS_UNISTD_H 1
+#  endif
+# endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
+#endif // !defined(BOOST_ASIO_HAS_UNISTD_H)
+#if defined(BOOST_ASIO_HAS_UNISTD_H)
+# include <unistd.h>
+#endif // defined(BOOST_ASIO_HAS_UNISTD_H)
+
+// Linux: epoll, eventfd and timerfd.
+#if defined(__linux__)
+# include <linux/version.h>
+# if !defined(BOOST_ASIO_HAS_EPOLL)
+#  if !defined(BOOST_ASIO_DISABLE_EPOLL)
+#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
+#    define BOOST_ASIO_HAS_EPOLL 1
+#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
+#  endif // !defined(BOOST_ASIO_DISABLE_EPOLL)
+# endif // !defined(BOOST_ASIO_HAS_EPOLL)
+# if !defined(BOOST_ASIO_HAS_EVENTFD)
+#  if !defined(BOOST_ASIO_DISABLE_EVENTFD)
+#   if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#    define BOOST_ASIO_HAS_EVENTFD 1
+#   endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#  endif // !defined(BOOST_ASIO_DISABLE_EVENTFD)
+# endif // !defined(BOOST_ASIO_HAS_EVENTFD)
+# if !defined(BOOST_ASIO_HAS_TIMERFD)
+#  if defined(BOOST_ASIO_HAS_EPOLL)
+#   if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+#    define BOOST_ASIO_HAS_TIMERFD 1
+#   endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+#  endif // defined(BOOST_ASIO_HAS_EPOLL)
+# endif // !defined(BOOST_ASIO_HAS_TIMERFD)
+#endif // defined(__linux__)
+
+// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.
+#if (defined(__MACH__) && defined(__APPLE__)) \
+  || defined(__FreeBSD__) \
+  || defined(__NetBSD__) \
+  || defined(__OpenBSD__)
+# if !defined(BOOST_ASIO_HAS_KQUEUE)
+#  if !defined(BOOST_ASIO_DISABLE_KQUEUE)
+#   define BOOST_ASIO_HAS_KQUEUE 1
+#  endif // !defined(BOOST_ASIO_DISABLE_KQUEUE)
+# endif // !defined(BOOST_ASIO_HAS_KQUEUE)
+#endif // (defined(__MACH__) && defined(__APPLE__))
+       //   || defined(__FreeBSD__)
+       //   || defined(__NetBSD__)
+       //   || defined(__OpenBSD__)
+
+// Solaris: /dev/poll.
+#if defined(__sun)
+# if !defined(BOOST_ASIO_HAS_DEV_POLL)
+#  if !defined(BOOST_ASIO_DISABLE_DEV_POLL)
+#   define BOOST_ASIO_HAS_DEV_POLL 1
+#  endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL)
+# endif // !defined(BOOST_ASIO_HAS_DEV_POLL)
+#endif // defined(__sun)
+
+// Serial ports.
+#if !defined(BOOST_ASIO_HAS_SERIAL_PORT)
+# if defined(BOOST_ASIO_HAS_IOCP) \
+  || !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+#  if !defined(__SYMBIAN32__)
+#   if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
+#    define BOOST_ASIO_HAS_SERIAL_PORT 1
+#   endif // !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
+#  endif // !defined(__SYMBIAN32__)
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+        //   || !defined(BOOST_ASIO_WINDOWS)
+        //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+        //   && !defined(__CYGWIN__)
+#endif // !defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+// Windows: stream handles.
+#if !defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
+# if !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
+#  if defined(BOOST_ASIO_HAS_IOCP)
+#   define BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE 1
+#  endif // defined(BOOST_ASIO_HAS_IOCP)
+# endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
+#endif // !defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
+
+// Windows: random access handles.
+#if !defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+# if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+#  if defined(BOOST_ASIO_HAS_IOCP)
+#   define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1
+#  endif // defined(BOOST_ASIO_HAS_IOCP)
+# endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+#endif // !defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+
+// Windows: object handles.
+#if !defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
+# if !defined(BOOST_ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)
+#  if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+#   if !defined(UNDER_CE) && !defined(BOOST_ASIO_WINDOWS_APP)
+#    define BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE 1
+#   endif // !defined(UNDER_CE) && !defined(BOOST_ASIO_WINDOWS_APP)
+#  endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OBJECT_HANDLE)
+#endif // !defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
+
+// Windows: OVERLAPPED wrapper.
+#if !defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+# if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+#  if defined(BOOST_ASIO_HAS_IOCP)
+#   define BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1
+#  endif // defined(BOOST_ASIO_HAS_IOCP)
+# endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+#endif // !defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
+
+// POSIX: stream-oriented file descriptors.
+#if !defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+# if !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
+#  if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+#   define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1
+#  endif // !defined(BOOST_ASIO_WINDOWS)
+         //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+         //   && !defined(__CYGWIN__)
+# endif // !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
+#endif // !defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+
+// UNIX domain sockets.
+#if !defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+# if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
+#  if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+#   define BOOST_ASIO_HAS_LOCAL_SOCKETS 1
+#  endif // !defined(BOOST_ASIO_WINDOWS)
+         //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+         //   && !defined(__CYGWIN__)
+# endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
+#endif // !defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+// Can use sigaction() instead of signal().
+#if !defined(BOOST_ASIO_HAS_SIGACTION)
+# if !defined(BOOST_ASIO_DISABLE_SIGACTION)
+#  if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+#   define BOOST_ASIO_HAS_SIGACTION 1
+#  endif // !defined(BOOST_ASIO_WINDOWS)
+         //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+         //   && !defined(__CYGWIN__)
+# endif // !defined(BOOST_ASIO_DISABLE_SIGACTION)
+#endif // !defined(BOOST_ASIO_HAS_SIGACTION)
+
+// Can use signal().
+#if !defined(BOOST_ASIO_HAS_SIGNAL)
+# if !defined(BOOST_ASIO_DISABLE_SIGNAL)
+#  if !defined(UNDER_CE)
+#   define BOOST_ASIO_HAS_SIGNAL 1
+#  endif // !defined(UNDER_CE)
+# endif // !defined(BOOST_ASIO_DISABLE_SIGNAL)
+#endif // !defined(BOOST_ASIO_HAS_SIGNAL)
+
+// Can use getaddrinfo() and getnameinfo().
+#if !defined(BOOST_ASIO_HAS_GETADDRINFO)
+# if !defined(BOOST_ASIO_DISABLE_GETADDRINFO)
+#  if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+#   if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
+#    define BOOST_ASIO_HAS_GETADDRINFO 1
+#   elif defined(UNDER_CE)
+#    define BOOST_ASIO_HAS_GETADDRINFO 1
+#   endif // defined(UNDER_CE)
+#  elif defined(__MACH__) && defined(__APPLE__)
+#   if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#    if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
+#     define BOOST_ASIO_HAS_GETADDRINFO 1
+#    endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
+#   else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#    define BOOST_ASIO_HAS_GETADDRINFO 1
+#   endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#  else // defined(__MACH__) && defined(__APPLE__)
+#   define BOOST_ASIO_HAS_GETADDRINFO 1
+#  endif // defined(__MACH__) && defined(__APPLE__)
+# endif // !defined(BOOST_ASIO_DISABLE_GETADDRINFO)
+#endif // !defined(BOOST_ASIO_HAS_GETADDRINFO)
+
+// Whether standard iostreams are disabled.
+#if !defined(BOOST_ASIO_NO_IOSTREAM)
+# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_IOSTREAM)
+#  define BOOST_ASIO_NO_IOSTREAM 1
+# endif // !defined(BOOST_NO_IOSTREAM)
+#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
+
+// Whether exception handling is disabled.
+#if !defined(BOOST_ASIO_NO_EXCEPTIONS)
+# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_EXCEPTIONS)
+#  define BOOST_ASIO_NO_EXCEPTIONS 1
+# endif // !defined(BOOST_NO_EXCEPTIONS)
+#endif // !defined(BOOST_ASIO_NO_EXCEPTIONS)
+
+// Whether the typeid operator is supported.
+#if !defined(BOOST_ASIO_NO_TYPEID)
+# if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_NO_TYPEID)
+#  define BOOST_ASIO_NO_TYPEID 1
+# endif // !defined(BOOST_NO_TYPEID)
+#endif // !defined(BOOST_ASIO_NO_TYPEID)
+
+// Threads.
+#if !defined(BOOST_ASIO_HAS_THREADS)
+# if !defined(BOOST_ASIO_DISABLE_THREADS)
+#  if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(__GNUC__) && !defined(__MINGW32__) \
+     && !defined(linux) && !defined(__linux) && !defined(__linux__)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(_MT) || defined(__MT__)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(_REENTRANT)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(__APPLE__)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  elif defined(_PTHREADS)
+#   define BOOST_ASIO_HAS_THREADS 1
+#  endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_THREADS)
+# endif // !defined(BOOST_ASIO_DISABLE_THREADS)
+#endif // !defined(BOOST_ASIO_HAS_THREADS)
+
+// POSIX threads.
+#if !defined(BOOST_ASIO_HAS_PTHREADS)
+# if defined(BOOST_ASIO_HAS_THREADS)
+#  if defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
+#   define BOOST_ASIO_HAS_PTHREADS 1
+#  elif defined(_POSIX_THREADS) && (_POSIX_THREADS + 0 >= 0)
+#   define BOOST_ASIO_HAS_PTHREADS 1
+#  endif // defined(BOOST_ASIO_HAS_BOOST_CONFIG) && defined(BOOST_HAS_PTHREADS)
+# endif // defined(BOOST_ASIO_HAS_THREADS)
+#endif // !defined(BOOST_ASIO_HAS_PTHREADS)
+
+// Helper to prevent macro expansion.
+#define BOOST_ASIO_PREVENT_MACRO_SUBSTITUTION
+
+// Helper to define in-class constants.
+#if !defined(BOOST_ASIO_STATIC_CONSTANT)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_STATIC_CONSTANT)
+#  define BOOST_ASIO_STATIC_CONSTANT(type, assignment) \
+    BOOST_STATIC_CONSTANT(type, assignment)
+# else // !defined(BOOST_ASIO_DISABLE_BOOST_STATIC_CONSTANT)
+#  define BOOST_ASIO_STATIC_CONSTANT(type, assignment) \
+    static const type assignment
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_STATIC_CONSTANT)
+#endif // !defined(BOOST_ASIO_STATIC_CONSTANT)
+
+// Boost array library.
+#if !defined(BOOST_ASIO_HAS_BOOST_ARRAY)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_ARRAY)
+#  define BOOST_ASIO_HAS_BOOST_ARRAY 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_ARRAY)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_ARRAY)
+
+// Boost assert macro.
+#if !defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_ASSERT)
+#  define BOOST_ASIO_HAS_BOOST_ASSERT 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_ASSERT)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_ASSERT)
+
+// Boost limits header.
+#if !defined(BOOST_ASIO_HAS_BOOST_LIMITS)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_LIMITS)
+#  define BOOST_ASIO_HAS_BOOST_LIMITS 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_LIMITS)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_LIMITS)
+
+// Boost throw_exception function.
+#if !defined(BOOST_ASIO_HAS_BOOST_THROW_EXCEPTION)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_THROW_EXCEPTION)
+#  define BOOST_ASIO_HAS_BOOST_THROW_EXCEPTION 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_THROW_EXCEPTION)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_THROW_EXCEPTION)
+
+// Boost regex library.
+#if !defined(BOOST_ASIO_HAS_BOOST_REGEX)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_REGEX)
+#  define BOOST_ASIO_HAS_BOOST_REGEX 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_REGEX)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_REGEX)
+
+// Boost bind function.
+#if !defined(BOOST_ASIO_HAS_BOOST_BIND)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_BIND)
+#  define BOOST_ASIO_HAS_BOOST_BIND 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_BIND)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_BIND)
+
+// Boost's BOOST_WORKAROUND macro.
+#if !defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
+# if !defined(BOOST_ASIO_DISABLE_BOOST_WORKAROUND)
+#  define BOOST_ASIO_HAS_BOOST_WORKAROUND 1
+# endif // !defined(BOOST_ASIO_DISABLE_BOOST_WORKAROUND)
+#endif // !defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
+
+// Microsoft Visual C++'s secure C runtime library.
+#if !defined(BOOST_ASIO_HAS_SECURE_RTL)
+# if !defined(BOOST_ASIO_DISABLE_SECURE_RTL)
+#  if defined(BOOST_ASIO_MSVC) \
+    && (BOOST_ASIO_MSVC >= 1400) \
+    && !defined(UNDER_CE)
+#   define BOOST_ASIO_HAS_SECURE_RTL 1
+#  endif // defined(BOOST_ASIO_MSVC)
+         // && (BOOST_ASIO_MSVC >= 1400)
+         // && !defined(UNDER_CE)
+# endif // !defined(BOOST_ASIO_DISABLE_SECURE_RTL)
+#endif // !defined(BOOST_ASIO_HAS_SECURE_RTL)
+
+// Handler hooking. Disabled for ancient Borland C++ and gcc compilers.
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+# if !defined(BOOST_ASIO_DISABLE_HANDLER_HOOKS)
+#  if defined(__GNUC__)
+#   if (__GNUC__ >= 3)
+#    define BOOST_ASIO_HAS_HANDLER_HOOKS 1
+#   endif // (__GNUC__ >= 3)
+#  elif !defined(__BORLANDC__)
+#   define BOOST_ASIO_HAS_HANDLER_HOOKS 1
+#  endif // !defined(__BORLANDC__)
+# endif // !defined(BOOST_ASIO_DISABLE_HANDLER_HOOKS)
+#endif // !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+
+// Support for the __thread keyword extension.
+#if !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
+# if defined(__linux__)
+#  if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#   if ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
+#    if !defined(__INTEL_COMPILER) && !defined(__ICL) \
+       && !(defined(__clang__) && defined(__ANDROID__))
+#     define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
+#     define BOOST_ASIO_THREAD_KEYWORD __thread
+#    elif defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
+#     define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
+#    endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100)
+           // && !(defined(__clang__) && defined(__ANDROID__))
+#   endif // ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)
+#  endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# endif // defined(__linux__)
+# if defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#  if (_MSC_VER >= 1700)
+#   define BOOST_ASIO_HAS_THREAD_KEYWORD_EXTENSION 1
+#   define BOOST_ASIO_THREAD_KEYWORD __declspec(thread)
+#  endif // (_MSC_VER >= 1700)
+# endif // defined(BOOST_ASIO_MSVC) && defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#endif // !defined(BOOST_ASIO_DISABLE_THREAD_KEYWORD_EXTENSION)
+#if !defined(BOOST_ASIO_THREAD_KEYWORD)
+# define BOOST_ASIO_THREAD_KEYWORD __thread
+#endif // !defined(BOOST_ASIO_THREAD_KEYWORD)
+
+// Support for POSIX ssize_t typedef.
+#if !defined(BOOST_ASIO_DISABLE_SSIZE_T)
+# if defined(__linux__) \
+   || (defined(__MACH__) && defined(__APPLE__))
+#  define BOOST_ASIO_HAS_SSIZE_T 1
+# endif // defined(__linux__)
+        //   || (defined(__MACH__) && defined(__APPLE__))
+#endif // !defined(BOOST_ASIO_DISABLE_SSIZE_T)
+
+// Helper macros to manage the transition away from the old services-based API.
+#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# define BOOST_ASIO_SVC_TPARAM , typename Service
+# define BOOST_ASIO_SVC_TPARAM_DEF1(d1) , typename Service d1
+# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2) , typename Service d1, d2
+# define BOOST_ASIO_SVC_TARG , Service
+# define BOOST_ASIO_SVC_T Service
+# define BOOST_ASIO_SVC_TPARAM1 , typename Service1
+# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1) , typename Service1 d1
+# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2) , typename Service1 d1, d2
+# define BOOST_ASIO_SVC_TARG1 , Service1
+# define BOOST_ASIO_SVC_T1 Service1
+# define BOOST_ASIO_SVC_ACCESS public
+#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# define BOOST_ASIO_SVC_TPARAM
+# define BOOST_ASIO_SVC_TPARAM_DEF1(d1)
+# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2)
+# define BOOST_ASIO_SVC_TARG
+// BOOST_ASIO_SVC_T is defined at each point of use.
+# define BOOST_ASIO_SVC_TPARAM1
+# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1)
+# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2)
+# define BOOST_ASIO_SVC_TARG1
+// BOOST_ASIO_SVC_T1 is defined at each point of use.
+# define BOOST_ASIO_SVC_ACCESS protected
+#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+
+// Helper macros to manage transition away from error_code return values.
+#if defined(BOOST_ASIO_NO_DEPRECATED)
+# define BOOST_ASIO_SYNC_OP_VOID void
+# define BOOST_ASIO_SYNC_OP_VOID_RETURN(e) return
+#else // defined(BOOST_ASIO_NO_DEPRECATED)
+# define BOOST_ASIO_SYNC_OP_VOID boost::system::error_code
+# define BOOST_ASIO_SYNC_OP_VOID_RETURN(e) return e
+#endif // defined(BOOST_ASIO_NO_DEPRECATED)
+
+// Newer gcc, clang need special treatment to suppress unused typedef warnings.
+#if defined(__clang__)
+# if defined(__apple_build_version__)
+#  if (__clang_major__ >= 7)
+#   define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__))
+#  endif // (__clang_major__ >= 7)
+# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \
+    || (__clang_major__ > 3)
+#  define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__))
+# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6))
+        //   || (__clang_major__ > 3)
+#elif defined(__GNUC__)
+# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
+#  define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__))
+# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
+#endif // defined(__GNUC__)
+#if !defined(BOOST_ASIO_UNUSED_TYPEDEF)
+# define BOOST_ASIO_UNUSED_TYPEDEF
+#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF)
+
+// Some versions of gcc generate spurious warnings about unused variables.
+#if defined(__GNUC__)
+# if (__GNUC__ >= 4)
+#  define BOOST_ASIO_UNUSED_VARIABLE __attribute__((__unused__))
+# endif // (__GNUC__ >= 4)
+#endif // defined(__GNUC__)
+#if !defined(BOOST_ASIO_UNUSED_VARIABLE)
+# define BOOST_ASIO_UNUSED_VARIABLE
+#endif // !defined(BOOST_ASIO_UNUSED_VARIABLE)
+
+// Support co_await on compilers known to allow it.
+#if !defined(BOOST_ASIO_HAS_CO_AWAIT)
+# if !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
+#  if defined(BOOST_ASIO_MSVC)
+#   if (_MSC_FULL_VER >= 190023506)
+#    if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
+#     define BOOST_ASIO_HAS_CO_AWAIT 1
+#    endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
+#   endif // (_MSC_FULL_VER >= 190023506)
+#  endif // defined(BOOST_ASIO_MSVC)
+# endif // !defined(BOOST_ASIO_DISABLE_CO_AWAIT)
+# if defined(__clang__)
+#  if (__cpp_coroutines >= 201703)
+#   if __has_include(<experimental/coroutine>)
+#    define BOOST_ASIO_HAS_CO_AWAIT 1
+#   endif // __has_include(<experimental/coroutine>)
+#  endif // (__cpp_coroutines >= 201703)
+# endif // defined(__clang__)
+#endif // !defined(BOOST_ASIO_HAS_CO_AWAIT)
+
+#endif // BOOST_ASIO_DETAIL_CONFIG_HPP

+ 416 - 0
cpir-read/boost/boost/asio/detail/consuming_buffers.hpp

@@ -0,0 +1,416 @@
+//
+// detail/consuming_buffers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
+#define BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/limits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Helper template to determine the maximum number of prepared buffers.
+template <typename Buffers>
+struct prepared_buffers_max
+{
+  enum { value = buffer_sequence_adapter_base::max_buffers };
+};
+
+template <typename Elem, std::size_t N>
+struct prepared_buffers_max<boost::array<Elem, N> >
+{
+  enum { value = N };
+};
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+template <typename Elem, std::size_t N>
+struct prepared_buffers_max<std::array<Elem, N> >
+{
+  enum { value = N };
+};
+
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+// A buffer sequence used to represent a subsequence of the buffers.
+template <typename Buffer, std::size_t MaxBuffers>
+struct prepared_buffers
+{
+  typedef Buffer value_type;
+  typedef const Buffer* const_iterator;
+
+  enum { max_buffers = MaxBuffers < 16 ? MaxBuffers : 16 };
+
+  prepared_buffers() : count(0) {}
+  const_iterator begin() const { return elems; }
+  const_iterator end() const { return elems + count; }
+
+  Buffer elems[max_buffers];
+  std::size_t count;
+};
+
+// A proxy for a sub-range in a list of buffers.
+template <typename Buffer, typename Buffers, typename Buffer_Iterator>
+class consuming_buffers
+{
+public:
+  typedef prepared_buffers<Buffer, prepared_buffers_max<Buffers>::value>
+    prepared_buffers_type;
+
+  // Construct to represent the entire list of buffers.
+  explicit consuming_buffers(const Buffers& buffers)
+    : buffers_(buffers),
+      total_consumed_(0),
+      next_elem_(0),
+      next_elem_offset_(0)
+  {
+    using boost::asio::buffer_size;
+    total_size_ = buffer_size(buffers);
+  }
+
+  // Determine if we are at the end of the buffers.
+  bool empty() const
+  {
+    return total_consumed_ >= total_size_;
+  }
+
+  // Get the buffer for a single transfer, with a size.
+  prepared_buffers_type prepare(std::size_t max_size)
+  {
+    prepared_buffers_type result;
+
+    Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
+    Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
+
+    std::advance(next, next_elem_);
+    std::size_t elem_offset = next_elem_offset_;
+    while (next != end && max_size > 0 && (result.count) < result.max_buffers)
+    {
+      Buffer next_buf = Buffer(*next) + elem_offset;
+      result.elems[result.count] = boost::asio::buffer(next_buf, max_size);
+      max_size -= result.elems[result.count].size();
+      elem_offset = 0;
+      if (result.elems[result.count].size() > 0)
+        ++result.count;
+      ++next;
+    }
+
+    return result;
+  }
+
+  // Consume the specified number of bytes from the buffers.
+  void consume(std::size_t size)
+  {
+    total_consumed_ += size;
+
+    Buffer_Iterator next = boost::asio::buffer_sequence_begin(buffers_);
+    Buffer_Iterator end = boost::asio::buffer_sequence_end(buffers_);
+
+    std::advance(next, next_elem_);
+    while (next != end && size > 0)
+    {
+      Buffer next_buf = Buffer(*next) + next_elem_offset_;
+      if (size < next_buf.size())
+      {
+        next_elem_offset_ += size;
+        size = 0;
+      }
+      else
+      {
+        size -= next_buf.size();
+        next_elem_offset_ = 0;
+        ++next_elem_;
+        ++next;
+      }
+    }
+  }
+
+  // Get the total number of bytes consumed from the buffers.
+  std::size_t total_consumed() const
+  {
+    return total_consumed_;
+  }
+
+private:
+  Buffers buffers_;
+  std::size_t total_size_;
+  std::size_t total_consumed_;
+  std::size_t next_elem_;
+  std::size_t next_elem_offset_;
+};
+
+// Base class of all consuming_buffers specialisations for single buffers.
+template <typename Buffer>
+class consuming_single_buffer
+{
+public:
+  // Construct to represent the entire list of buffers.
+  template <typename Buffer1>
+  explicit consuming_single_buffer(const Buffer1& buffer)
+    : buffer_(buffer),
+      total_consumed_(0)
+  {
+  }
+
+  // Determine if we are at the end of the buffers.
+  bool empty() const
+  {
+    return total_consumed_ >= buffer_.size();
+  }
+
+  // Get the buffer for a single transfer, with a size.
+  Buffer prepare(std::size_t max_size)
+  {
+    return boost::asio::buffer(buffer_ + total_consumed_, max_size);
+  }
+
+  // Consume the specified number of bytes from the buffers.
+  void consume(std::size_t size)
+  {
+    total_consumed_ += size;
+  }
+
+  // Get the total number of bytes consumed from the buffers.
+  std::size_t total_consumed() const
+  {
+    return total_consumed_;
+  }
+
+private:
+  Buffer buffer_;
+  std::size_t total_consumed_;
+};
+
+template <>
+class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>
+{
+public:
+  explicit consuming_buffers(const mutable_buffer& buffer)
+    : consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>(buffer)
+  {
+  }
+};
+
+template <>
+class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
+{
+public:
+  explicit consuming_buffers(const mutable_buffer& buffer)
+    : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
+  {
+  }
+};
+
+template <>
+class consuming_buffers<const_buffer, const_buffer, const const_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
+{
+public:
+  explicit consuming_buffers(const const_buffer& buffer)
+    : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
+  {
+  }
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <>
+class consuming_buffers<mutable_buffer,
+    mutable_buffers_1, const mutable_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>
+{
+public:
+  explicit consuming_buffers(const mutable_buffers_1& buffer)
+    : consuming_single_buffer<BOOST_ASIO_MUTABLE_BUFFER>(buffer)
+  {
+  }
+};
+
+template <>
+class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
+{
+public:
+  explicit consuming_buffers(const mutable_buffers_1& buffer)
+    : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
+  {
+  }
+};
+
+template <>
+class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>
+  : public consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>
+{
+public:
+  explicit consuming_buffers(const const_buffers_1& buffer)
+    : consuming_single_buffer<BOOST_ASIO_CONST_BUFFER>(buffer)
+  {
+  }
+};
+
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
+template <typename Buffer, typename Elem>
+class consuming_buffers<Buffer, boost::array<Elem, 2>,
+    typename boost::array<Elem, 2>::const_iterator>
+{
+public:
+  // Construct to represent the entire list of buffers.
+  explicit consuming_buffers(const boost::array<Elem, 2>& buffers)
+    : buffers_(buffers),
+      total_consumed_(0)
+  {
+  }
+
+  // Determine if we are at the end of the buffers.
+  bool empty() const
+  {
+    return total_consumed_ >=
+      Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
+  }
+
+  // Get the buffer for a single transfer, with a size.
+  boost::array<Buffer, 2> prepare(std::size_t max_size)
+  {
+    boost::array<Buffer, 2> result = {{
+      Buffer(buffers_[0]), Buffer(buffers_[1]) }};
+    std::size_t buffer0_size = result[0].size();
+    result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
+    result[1] = boost::asio::buffer(
+        result[1] + (total_consumed_ < buffer0_size
+          ? 0 : total_consumed_ - buffer0_size),
+        max_size - result[0].size());
+    return result;
+  }
+
+  // Consume the specified number of bytes from the buffers.
+  void consume(std::size_t size)
+  {
+    total_consumed_ += size;
+  }
+
+  // Get the total number of bytes consumed from the buffers.
+  std::size_t total_consumed() const
+  {
+    return total_consumed_;
+  }
+
+private:
+  boost::array<Elem, 2> buffers_;
+  std::size_t total_consumed_;
+};
+
+#if defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+template <typename Buffer, typename Elem>
+class consuming_buffers<Buffer, std::array<Elem, 2>,
+    typename std::array<Elem, 2>::const_iterator>
+{
+public:
+  // Construct to represent the entire list of buffers.
+  explicit consuming_buffers(const std::array<Elem, 2>& buffers)
+    : buffers_(buffers),
+      total_consumed_(0)
+  {
+  }
+
+  // Determine if we are at the end of the buffers.
+  bool empty() const
+  {
+    return total_consumed_ >=
+      Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
+  }
+
+  // Get the buffer for a single transfer, with a size.
+  std::array<Buffer, 2> prepare(std::size_t max_size)
+  {
+    std::array<Buffer, 2> result = {{
+      Buffer(buffers_[0]), Buffer(buffers_[1]) }};
+    std::size_t buffer0_size = result[0].size();
+    result[0] = boost::asio::buffer(result[0] + total_consumed_, max_size);
+    result[1] = boost::asio::buffer(
+        result[1] + (total_consumed_ < buffer0_size
+          ? 0 : total_consumed_ - buffer0_size),
+        max_size - result[0].size());
+    return result;
+  }
+
+  // Consume the specified number of bytes from the buffers.
+  void consume(std::size_t size)
+  {
+    total_consumed_ += size;
+  }
+
+  // Get the total number of bytes consumed from the buffers.
+  std::size_t total_consumed() const
+  {
+    return total_consumed_;
+  }
+
+private:
+  std::array<Elem, 2> buffers_;
+  std::size_t total_consumed_;
+};
+
+#endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
+
+// Specialisation for null_buffers to ensure that the null_buffers type is
+// always passed through to the underlying read or write operation.
+template <typename Buffer>
+class consuming_buffers<Buffer, null_buffers, const mutable_buffer*>
+  : public boost::asio::null_buffers
+{
+public:
+  consuming_buffers(const null_buffers&)
+  {
+    // No-op.
+  }
+
+  bool empty()
+  {
+    return false;
+  }
+
+  null_buffers prepare(std::size_t)
+  {
+    return null_buffers();
+  }
+
+  void consume(std::size_t)
+  {
+    // No-op.
+  }
+
+  std::size_t total_consumed() const
+  {
+    return 0;
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_CONSUMING_BUFFERS_HPP

+ 33 - 0
cpir-read/boost/boost/asio/detail/cstddef.hpp

@@ -0,0 +1,33 @@
+//
+// detail/cstddef.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CSTDDEF_HPP
+#define BOOST_ASIO_DETAIL_CSTDDEF_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace asio {
+
+#if defined(BOOST_ASIO_HAS_NULLPTR)
+using std::nullptr_t;
+#else // defined(BOOST_ASIO_HAS_NULLPTR)
+struct nullptr_t {};
+#endif // defined(BOOST_ASIO_HAS_NULLPTR)
+
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_CSTDDEF_HPP

+ 62 - 0
cpir-read/boost/boost/asio/detail/cstdint.hpp

@@ -0,0 +1,62 @@
+//
+// detail/cstdint.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_CSTDINT_HPP
+#define BOOST_ASIO_DETAIL_CSTDINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_CSTDINT)
+# include <cstdint>
+#else // defined(BOOST_ASIO_HAS_CSTDINT)
+# include <boost/cstdint.hpp>
+#endif // defined(BOOST_ASIO_HAS_CSTDINT)
+
+namespace boost {
+namespace asio {
+
+#if defined(BOOST_ASIO_HAS_CSTDINT)
+using std::int16_t;
+using std::int_least16_t;
+using std::uint16_t;
+using std::uint_least16_t;
+using std::int32_t;
+using std::int_least32_t;
+using std::uint32_t;
+using std::uint_least32_t;
+using std::int64_t;
+using std::int_least64_t;
+using std::uint64_t;
+using std::uint_least64_t;
+using std::uintmax_t;
+#else // defined(BOOST_ASIO_HAS_CSTDINT)
+using boost::int16_t;
+using boost::int_least16_t;
+using boost::uint16_t;
+using boost::uint_least16_t;
+using boost::int32_t;
+using boost::int_least32_t;
+using boost::uint32_t;
+using boost::uint_least32_t;
+using boost::int64_t;
+using boost::int_least64_t;
+using boost::uint64_t;
+using boost::uint_least64_t;
+using boost::uintmax_t;
+#endif // defined(BOOST_ASIO_HAS_CSTDINT)
+
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_CSTDINT_HPP

+ 34 - 0
cpir-read/boost/boost/asio/detail/date_time_fwd.hpp

@@ -0,0 +1,34 @@
+//
+// detail/date_time_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DATE_TIME_FWD_HPP
+#define BOOST_ASIO_DETAIL_DATE_TIME_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+namespace boost {
+namespace date_time {
+
+template<class T, class TimeSystem>
+class base_time;
+
+} // namespace date_time
+namespace posix_time {
+
+class ptime;
+
+} // namespace posix_time
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_DATE_TIME_FWD_HPP

+ 280 - 0
cpir-read/boost/boost/asio/detail/deadline_timer_service.hpp

@@ -0,0 +1,280 @@
+//
+// detail/deadline_timer_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_queue_ptime.hpp>
+#include <boost/asio/detail/timer_scheduler.hpp>
+#include <boost/asio/detail/wait_handler.hpp>
+#include <boost/asio/detail/wait_op.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <chrono>
+# include <thread>
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+class deadline_timer_service
+  : public service_base<deadline_timer_service<Time_Traits> >
+{
+public:
+  // The time type.
+  typedef typename Time_Traits::time_type time_type;
+
+  // The duration type.
+  typedef typename Time_Traits::duration_type duration_type;
+
+  // The implementation type of the timer. This type is dependent on the
+  // underlying implementation of the timer service.
+  struct implementation_type
+    : private boost::asio::detail::noncopyable
+  {
+    time_type expiry;
+    bool might_have_pending_waits;
+    typename timer_queue<Time_Traits>::per_timer_data timer_data;
+  };
+
+  // Constructor.
+  deadline_timer_service(boost::asio::io_context& io_context)
+    : service_base<deadline_timer_service<Time_Traits> >(io_context),
+      scheduler_(boost::asio::use_service<timer_scheduler>(io_context))
+  {
+    scheduler_.init_task();
+    scheduler_.add_timer_queue(timer_queue_);
+  }
+
+  // Destructor.
+  ~deadline_timer_service()
+  {
+    scheduler_.remove_timer_queue(timer_queue_);
+  }
+
+  // Destroy all user-defined handler objects owned by the service.
+  void shutdown()
+  {
+  }
+
+  // Construct a new timer implementation.
+  void construct(implementation_type& impl)
+  {
+    impl.expiry = time_type();
+    impl.might_have_pending_waits = false;
+  }
+
+  // Destroy a timer implementation.
+  void destroy(implementation_type& impl)
+  {
+    boost::system::error_code ec;
+    cancel(impl, ec);
+  }
+
+  // Move-construct a new serial port implementation.
+  void move_construct(implementation_type& impl,
+      implementation_type& other_impl)
+  {
+    scheduler_.move_timer(timer_queue_, impl.timer_data, other_impl.timer_data);
+
+    impl.expiry = other_impl.expiry;
+    other_impl.expiry = time_type();
+
+    impl.might_have_pending_waits = other_impl.might_have_pending_waits;
+    other_impl.might_have_pending_waits = false;
+  }
+
+  // Move-assign from another serial port implementation.
+  void move_assign(implementation_type& impl,
+      deadline_timer_service& other_service,
+      implementation_type& other_impl)
+  {
+    if (this != &other_service)
+      if (impl.might_have_pending_waits)
+        scheduler_.cancel_timer(timer_queue_, impl.timer_data);
+
+    other_service.scheduler_.move_timer(other_service.timer_queue_,
+        impl.timer_data, other_impl.timer_data);
+
+    impl.expiry = other_impl.expiry;
+    other_impl.expiry = time_type();
+
+    impl.might_have_pending_waits = other_impl.might_have_pending_waits;
+    other_impl.might_have_pending_waits = false;
+  }
+
+  // Cancel any asynchronous wait operations associated with the timer.
+  std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
+  {
+    if (!impl.might_have_pending_waits)
+    {
+      ec = boost::system::error_code();
+      return 0;
+    }
+
+    BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
+          "deadline_timer", &impl, 0, "cancel"));
+
+    std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data);
+    impl.might_have_pending_waits = false;
+    ec = boost::system::error_code();
+    return count;
+  }
+
+  // Cancels one asynchronous wait operation associated with the timer.
+  std::size_t cancel_one(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    if (!impl.might_have_pending_waits)
+    {
+      ec = boost::system::error_code();
+      return 0;
+    }
+
+    BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
+          "deadline_timer", &impl, 0, "cancel_one"));
+
+    std::size_t count = scheduler_.cancel_timer(
+        timer_queue_, impl.timer_data, 1);
+    if (count == 0)
+      impl.might_have_pending_waits = false;
+    ec = boost::system::error_code();
+    return count;
+  }
+
+  // Get the expiry time for the timer as an absolute time.
+  time_type expiry(const implementation_type& impl) const
+  {
+    return impl.expiry;
+  }
+
+  // Get the expiry time for the timer as an absolute time.
+  time_type expires_at(const implementation_type& impl) const
+  {
+    return impl.expiry;
+  }
+
+  // Get the expiry time for the timer relative to now.
+  duration_type expires_from_now(const implementation_type& impl) const
+  {
+    return Time_Traits::subtract(this->expiry(impl), Time_Traits::now());
+  }
+
+  // Set the expiry time for the timer as an absolute time.
+  std::size_t expires_at(implementation_type& impl,
+      const time_type& expiry_time, boost::system::error_code& ec)
+  {
+    std::size_t count = cancel(impl, ec);
+    impl.expiry = expiry_time;
+    ec = boost::system::error_code();
+    return count;
+  }
+
+  // Set the expiry time for the timer relative to now.
+  std::size_t expires_after(implementation_type& impl,
+      const duration_type& expiry_time, boost::system::error_code& ec)
+  {
+    return expires_at(impl,
+        Time_Traits::add(Time_Traits::now(), expiry_time), ec);
+  }
+
+  // Set the expiry time for the timer relative to now.
+  std::size_t expires_from_now(implementation_type& impl,
+      const duration_type& expiry_time, boost::system::error_code& ec)
+  {
+    return expires_at(impl,
+        Time_Traits::add(Time_Traits::now(), expiry_time), ec);
+  }
+
+  // Perform a blocking wait on the timer.
+  void wait(implementation_type& impl, boost::system::error_code& ec)
+  {
+    time_type now = Time_Traits::now();
+    ec = boost::system::error_code();
+    while (Time_Traits::less_than(now, impl.expiry) && !ec)
+    {
+      this->do_wait(Time_Traits::to_posix_duration(
+            Time_Traits::subtract(impl.expiry, now)), ec);
+      now = Time_Traits::now();
+    }
+  }
+
+  // Start an asynchronous wait on the timer.
+  template <typename Handler>
+  void async_wait(implementation_type& impl, Handler& handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef wait_handler<Handler> op;
+    typename op::ptr p = { boost::asio::detail::addressof(handler),
+      op::ptr::allocate(handler), 0 };
+    p.p = new (p.v) op(handler);
+
+    impl.might_have_pending_waits = true;
+
+    BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
+          *p.p, "deadline_timer", &impl, 0, "async_wait"));
+
+    scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p);
+    p.v = p.p = 0;
+  }
+
+private:
+  // Helper function to wait given a duration type. The duration type should
+  // either be of type boost::posix_time::time_duration, or implement the
+  // required subset of its interface.
+  template <typename Duration>
+  void do_wait(const Duration& timeout, boost::system::error_code& ec)
+  {
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    std::this_thread::sleep_for(
+        std::chrono::seconds(timeout.total_seconds())
+        + std::chrono::microseconds(timeout.total_microseconds()));
+    ec = boost::system::error_code();
+#else // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+    ::timeval tv;
+    tv.tv_sec = timeout.total_seconds();
+    tv.tv_usec = timeout.total_microseconds() % 1000000;
+    socket_ops::select(0, 0, 0, 0, &tv, ec);
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  }
+
+  // The queue of timers.
+  timer_queue<Time_Traits> timer_queue_;
+
+  // The object that schedules and executes timers. Usually a reactor.
+  timer_scheduler& scheduler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP

+ 38 - 0
cpir-read/boost/boost/asio/detail/dependent_type.hpp

@@ -0,0 +1,38 @@
+//
+// detail/dependent_type.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DEPENDENT_TYPE_HPP
+#define BOOST_ASIO_DETAIL_DEPENDENT_TYPE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename DependsOn, typename T>
+struct dependent_type
+{
+  typedef T type;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_DEPENDENT_TYPE_HPP

+ 123 - 0
cpir-read/boost/boost/asio/detail/descriptor_ops.hpp

@@ -0,0 +1,123 @@
+//
+// detail/descriptor_ops.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_OPS_HPP
+#define BOOST_ASIO_DETAIL_DESCRIPTOR_OPS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+
+#include <cstddef>
+#include <boost/asio/error.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace descriptor_ops {
+
+// Descriptor state bits.
+enum
+{
+  // The user wants a non-blocking descriptor.
+  user_set_non_blocking = 1,
+
+  // The descriptor has been set non-blocking.
+  internal_non_blocking = 2,
+
+  // Helper "state" used to determine whether the descriptor is non-blocking.
+  non_blocking = user_set_non_blocking | internal_non_blocking,
+
+  // The descriptor may have been dup()-ed.
+  possible_dup = 4
+};
+
+typedef unsigned char state_type;
+
+template <typename ReturnType>
+inline ReturnType error_wrapper(ReturnType return_value,
+    boost::system::error_code& ec)
+{
+  ec = boost::system::error_code(errno,
+      boost::asio::error::get_system_category());
+  return return_value;
+}
+
+BOOST_ASIO_DECL int open(const char* path, int flags,
+    boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int close(int d, state_type& state,
+    boost::system::error_code& ec);
+
+BOOST_ASIO_DECL bool set_user_non_blocking(int d,
+    state_type& state, bool value, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL bool set_internal_non_blocking(int d,
+    state_type& state, bool value, boost::system::error_code& ec);
+
+typedef iovec buf;
+
+BOOST_ASIO_DECL std::size_t sync_read(int d, state_type state, buf* bufs,
+    std::size_t count, bool all_empty, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL bool non_blocking_read(int d, buf* bufs, std::size_t count,
+    boost::system::error_code& ec, std::size_t& bytes_transferred);
+
+BOOST_ASIO_DECL std::size_t sync_write(int d, state_type state,
+    const buf* bufs, std::size_t count, bool all_empty,
+    boost::system::error_code& ec);
+
+BOOST_ASIO_DECL bool non_blocking_write(int d,
+    const buf* bufs, std::size_t count,
+    boost::system::error_code& ec, std::size_t& bytes_transferred);
+
+BOOST_ASIO_DECL int ioctl(int d, state_type& state, long cmd,
+    ioctl_arg_type* arg, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int fcntl(int d, int cmd, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int fcntl(int d, int cmd,
+    long arg, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int poll_read(int d,
+    state_type state, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int poll_write(int d,
+    state_type state, boost::system::error_code& ec);
+
+BOOST_ASIO_DECL int poll_error(int d,
+    state_type state, boost::system::error_code& ec);
+
+} // namespace descriptor_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/descriptor_ops.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_WINDOWS)
+       //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+       //   && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_OPS_HPP

+ 130 - 0
cpir-read/boost/boost/asio/detail/descriptor_read_op.hpp

@@ -0,0 +1,130 @@
+//
+// detail/descriptor_read_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP
+#define BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class descriptor_read_op_base : public reactor_op
+{
+public:
+  descriptor_read_op_base(int descriptor,
+      const MutableBufferSequence& buffers, func_type complete_func)
+    : reactor_op(&descriptor_read_op_base::do_perform, complete_func),
+      descriptor_(descriptor),
+      buffers_(buffers)
+  {
+  }
+
+  static status do_perform(reactor_op* base)
+  {
+    descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base));
+
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(o->buffers_);
+
+    status result = descriptor_ops::non_blocking_read(o->descriptor_,
+        bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
+      ? done : not_done;
+
+    BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read",
+          o->ec_, o->bytes_transferred_));
+
+    return result;
+  }
+
+private:
+  int descriptor_;
+  MutableBufferSequence buffers_;
+};
+
+template <typename MutableBufferSequence, typename Handler>
+class descriptor_read_op
+  : public descriptor_read_op_base<MutableBufferSequence>
+{
+public:
+  BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
+
+  descriptor_read_op(int descriptor,
+      const MutableBufferSequence& buffers, Handler& handler)
+    : descriptor_read_op_base<MutableBufferSequence>(
+        descriptor, buffers, &descriptor_read_op::do_complete),
+      handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+  {
+    handler_work<Handler>::start(handler_);
+  }
+
+  static void do_complete(void* owner, operation* base,
+      const boost::system::error_code& /*ec*/,
+      std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
+    ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+    handler_work<Handler> w(o->handler_);
+
+    BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+    // Make a copy of the handler so that the memory can be deallocated before
+    // the upcall is made. Even if we're not about to make an upcall, a
+    // sub-object of the handler may be the true owner of the memory associated
+    // with the handler. Consequently, a local copy of the handler is required
+    // to ensure that any owning sub-object remains valid until after we have
+    // deallocated the memory here.
+    detail::binder2<Handler, boost::system::error_code, std::size_t>
+      handler(o->handler_, o->ec_, o->bytes_transferred_);
+    p.h = boost::asio::detail::addressof(handler.handler_);
+    p.reset();
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      fenced_block b(fenced_block::half);
+      BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
+      w.complete(handler, handler.handler_);
+      BOOST_ASIO_HANDLER_INVOCATION_END;
+    }
+  }
+
+private:
+  Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP

+ 130 - 0
cpir-read/boost/boost/asio/detail/descriptor_write_op.hpp

@@ -0,0 +1,130 @@
+//
+// detail/descriptor_write_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP
+#define BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_work.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence>
+class descriptor_write_op_base : public reactor_op
+{
+public:
+  descriptor_write_op_base(int descriptor,
+      const ConstBufferSequence& buffers, func_type complete_func)
+    : reactor_op(&descriptor_write_op_base::do_perform, complete_func),
+      descriptor_(descriptor),
+      buffers_(buffers)
+  {
+  }
+
+  static status do_perform(reactor_op* base)
+  {
+    descriptor_write_op_base* o(static_cast<descriptor_write_op_base*>(base));
+
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(o->buffers_);
+
+    status result = descriptor_ops::non_blocking_write(o->descriptor_,
+        bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
+      ? done : not_done;
+
+    BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_write",
+          o->ec_, o->bytes_transferred_));
+
+    return result;
+  }
+
+private:
+  int descriptor_;
+  ConstBufferSequence buffers_;
+};
+
+template <typename ConstBufferSequence, typename Handler>
+class descriptor_write_op
+  : public descriptor_write_op_base<ConstBufferSequence>
+{
+public:
+  BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
+
+  descriptor_write_op(int descriptor,
+      const ConstBufferSequence& buffers, Handler& handler)
+    : descriptor_write_op_base<ConstBufferSequence>(
+        descriptor, buffers, &descriptor_write_op::do_complete),
+      handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+  {
+    handler_work<Handler>::start(handler_);
+  }
+
+  static void do_complete(void* owner, operation* base,
+      const boost::system::error_code& /*ec*/,
+      std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
+    ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
+    handler_work<Handler> w(o->handler_);
+
+    BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+    // Make a copy of the handler so that the memory can be deallocated before
+    // the upcall is made. Even if we're not about to make an upcall, a
+    // sub-object of the handler may be the true owner of the memory associated
+    // with the handler. Consequently, a local copy of the handler is required
+    // to ensure that any owning sub-object remains valid until after we have
+    // deallocated the memory here.
+    detail::binder2<Handler, boost::system::error_code, std::size_t>
+      handler(o->handler_, o->ec_, o->bytes_transferred_);
+    p.h = boost::asio::detail::addressof(handler.handler_);
+    p.reset();
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      fenced_block b(fenced_block::half);
+      BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
+      w.complete(handler, handler.handler_);
+      BOOST_ASIO_HANDLER_INVOCATION_END;
+    }
+  }
+
+private:
+  Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP

+ 220 - 0
cpir-read/boost/boost/asio/detail/dev_poll_reactor.hpp

@@ -0,0 +1,220 @@
+//
+// detail/dev_poll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#include <cstddef>
+#include <vector>
+#include <sys/devpoll.h>
+#include <boost/asio/detail/hash_map.hpp>
+#include <boost/asio/detail/limits.hpp>
+#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/reactor_op_queue.hpp>
+#include <boost/asio/detail/select_interrupter.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
+#include <boost/asio/detail/wait_op.hpp>
+#include <boost/asio/execution_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class dev_poll_reactor
+  : public execution_context_service_base<dev_poll_reactor>
+{
+public:
+  enum op_types { read_op = 0, write_op = 1,
+    connect_op = 1, except_op = 2, max_ops = 3 };
+
+  // Per-descriptor data.
+  struct per_descriptor_data
+  {
+  };
+
+  // Constructor.
+  BOOST_ASIO_DECL dev_poll_reactor(boost::asio::execution_context& ctx);
+
+  // Destructor.
+  BOOST_ASIO_DECL ~dev_poll_reactor();
+
+  // Destroy all user-defined handler objects owned by the service.
+  BOOST_ASIO_DECL void shutdown();
+
+  // Recreate internal descriptors following a fork.
+  BOOST_ASIO_DECL void notify_fork(
+      boost::asio::execution_context::fork_event fork_ev);
+
+  // Initialise the task.
+  BOOST_ASIO_DECL void init_task();
+
+  // Register a socket with the reactor. Returns 0 on success, system error
+  // code on failure.
+  BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&);
+
+  // Register a descriptor with an associated single operation. Returns 0 on
+  // success, system error code on failure.
+  BOOST_ASIO_DECL int register_internal_descriptor(
+      int op_type, socket_type descriptor,
+      per_descriptor_data& descriptor_data, reactor_op* op);
+
+  // Move descriptor registration from one descriptor_data object to another.
+  BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
+      per_descriptor_data& target_descriptor_data,
+      per_descriptor_data& source_descriptor_data);
+
+  // Post a reactor operation for immediate completion.
+  void post_immediate_completion(reactor_op* op, bool is_continuation)
+  {
+    scheduler_.post_immediate_completion(op, is_continuation);
+  }
+
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
+      per_descriptor_data&, reactor_op* op,
+      bool is_continuation, bool allow_speculative);
+
+  // Cancel all operations associated with the given descriptor. The
+  // handlers associated with the descriptor will be invoked with the
+  // operation_aborted error.
+  BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
+
+  // Cancel any operations that are running against the descriptor and remove
+  // its registration from the reactor. The reactor resources associated with
+  // the descriptor must be released by calling cleanup_descriptor_data.
+  BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
+      per_descriptor_data&, bool closing);
+
+  // Remove the descriptor's registration from the reactor. The reactor
+  // resources associated with the descriptor must be released by calling
+  // cleanup_descriptor_data.
+  BOOST_ASIO_DECL void deregister_internal_descriptor(
+      socket_type descriptor, per_descriptor_data&);
+
+  // Perform any post-deregistration cleanup tasks associated with the
+  // descriptor data.
+  BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
+
+  // Add a new timer queue to the reactor.
+  template <typename Time_Traits>
+  void add_timer_queue(timer_queue<Time_Traits>& queue);
+
+  // Remove a timer queue from the reactor.
+  template <typename Time_Traits>
+  void remove_timer_queue(timer_queue<Time_Traits>& queue);
+
+  // Schedule a new operation in the given timer queue to expire at the
+  // specified absolute time.
+  template <typename Time_Traits>
+  void schedule_timer(timer_queue<Time_Traits>& queue,
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
+
+  // Cancel the timer operations associated with the given token. Returns the
+  // number of operations that have been posted or dispatched.
+  template <typename Time_Traits>
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer,
+      std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
+
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& target,
+      typename timer_queue<Time_Traits>::per_timer_data& source);
+
+  // Run /dev/poll once until interrupted or events are ready to be dispatched.
+  BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
+
+  // Interrupt the select loop.
+  BOOST_ASIO_DECL void interrupt();
+
+private:
+  // Create the /dev/poll file descriptor. Throws an exception if the descriptor
+  // cannot be created.
+  BOOST_ASIO_DECL static int do_dev_poll_create();
+
+  // Helper function to add a new timer queue.
+  BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+  // Helper function to remove a timer queue.
+  BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
+
+  // Get the timeout value for the /dev/poll DP_POLL operation. The timeout
+  // value is returned as a number of milliseconds. A return value of -1
+  // indicates that the poll should block indefinitely.
+  BOOST_ASIO_DECL int get_timeout(int msec);
+
+  // Cancel all operations associated with the given descriptor. The do_cancel
+  // function of the handler objects will be invoked. This function does not
+  // acquire the dev_poll_reactor's mutex.
+  BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor,
+      const boost::system::error_code& ec);
+
+  // Add a pending event entry for the given descriptor.
+  BOOST_ASIO_DECL ::pollfd& add_pending_event_change(int descriptor);
+
+  // The scheduler implementation used to post completions.
+  scheduler& scheduler_;
+
+  // Mutex to protect access to internal data.
+  boost::asio::detail::mutex mutex_;
+
+  // The /dev/poll file descriptor.
+  int dev_poll_fd_;
+
+  // Vector of /dev/poll events waiting to be written to the descriptor.
+  std::vector< ::pollfd> pending_event_changes_;
+
+  // Hash map to associate a descriptor with a pending event change index.
+  hash_map<int, std::size_t> pending_event_change_index_;
+
+  // The interrupter is used to break a blocking DP_POLL operation.
+  select_interrupter interrupter_;
+
+  // The queues of read, write and except operations.
+  reactor_op_queue<socket_type> op_queue_[max_ops];
+
+  // The timer queues.
+  timer_queue_set timer_queues_;
+
+  // Whether the service has been shut down.
+  bool shutdown_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/impl/dev_poll_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/dev_poll_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP

+ 268 - 0
cpir-read/boost/boost/asio/detail/epoll_reactor.hpp

@@ -0,0 +1,268 @@
+//
+// detail/epoll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include <boost/asio/detail/atomic_count.hpp>
+#include <boost/asio/detail/conditionally_enabled_mutex.hpp>
+#include <boost/asio/detail/limits.hpp>
+#include <boost/asio/detail/object_pool.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+#include <boost/asio/detail/select_interrupter.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
+#include <boost/asio/detail/wait_op.hpp>
+#include <boost/asio/execution_context.hpp>
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# include <sys/timerfd.h>
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class epoll_reactor
+  : public execution_context_service_base<epoll_reactor>
+{
+private:
+  // The mutex type used by this reactor.
+  typedef conditionally_enabled_mutex mutex;
+
+public:
+  enum op_types { read_op = 0, write_op = 1,
+    connect_op = 1, except_op = 2, max_ops = 3 };
+
+  // Per-descriptor queues.
+  class descriptor_state : operation
+  {
+    friend class epoll_reactor;
+    friend class object_pool_access;
+
+    descriptor_state* next_;
+    descriptor_state* prev_;
+
+    mutex mutex_;
+    epoll_reactor* reactor_;
+    int descriptor_;
+    uint32_t registered_events_;
+    op_queue<reactor_op> op_queue_[max_ops];
+    bool try_speculative_[max_ops];
+    bool shutdown_;
+
+    BOOST_ASIO_DECL descriptor_state(bool locking);
+    void set_ready_events(uint32_t events) { task_result_ = events; }
+    void add_ready_events(uint32_t events) { task_result_ |= events; }
+    BOOST_ASIO_DECL operation* perform_io(uint32_t events);
+    BOOST_ASIO_DECL static void do_complete(
+        void* owner, operation* base,
+        const boost::system::error_code& ec, std::size_t bytes_transferred);
+  };
+
+  // Per-descriptor data.
+  typedef descriptor_state* per_descriptor_data;
+
+  // Constructor.
+  BOOST_ASIO_DECL epoll_reactor(boost::asio::execution_context& ctx);
+
+  // Destructor.
+  BOOST_ASIO_DECL ~epoll_reactor();
+
+  // Destroy all user-defined handler objects owned by the service.
+  BOOST_ASIO_DECL void shutdown();
+
+  // Recreate internal descriptors following a fork.
+  BOOST_ASIO_DECL void notify_fork(
+      boost::asio::execution_context::fork_event fork_ev);
+
+  // Initialise the task.
+  BOOST_ASIO_DECL void init_task();
+
+  // Register a socket with the reactor. Returns 0 on success, system error
+  // code on failure.
+  BOOST_ASIO_DECL int register_descriptor(socket_type descriptor,
+      per_descriptor_data& descriptor_data);
+
+  // Register a descriptor with an associated single operation. Returns 0 on
+  // success, system error code on failure.
+  BOOST_ASIO_DECL int register_internal_descriptor(
+      int op_type, socket_type descriptor,
+      per_descriptor_data& descriptor_data, reactor_op* op);
+
+  // Move descriptor registration from one descriptor_data object to another.
+  BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
+      per_descriptor_data& target_descriptor_data,
+      per_descriptor_data& source_descriptor_data);
+
+  // Post a reactor operation for immediate completion.
+  void post_immediate_completion(reactor_op* op, bool is_continuation)
+  {
+    scheduler_.post_immediate_completion(op, is_continuation);
+  }
+
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
+      per_descriptor_data& descriptor_data, reactor_op* op,
+      bool is_continuation, bool allow_speculative);
+
+  // Cancel all operations associated with the given descriptor. The
+  // handlers associated with the descriptor will be invoked with the
+  // operation_aborted error.
+  BOOST_ASIO_DECL void cancel_ops(socket_type descriptor,
+      per_descriptor_data& descriptor_data);
+
+  // Cancel any operations that are running against the descriptor and remove
+  // its registration from the reactor. The reactor resources associated with
+  // the descriptor must be released by calling cleanup_descriptor_data.
+  BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
+      per_descriptor_data& descriptor_data, bool closing);
+
+  // Remove the descriptor's registration from the reactor. The reactor
+  // resources associated with the descriptor must be released by calling
+  // cleanup_descriptor_data.
+  BOOST_ASIO_DECL void deregister_internal_descriptor(
+      socket_type descriptor, per_descriptor_data& descriptor_data);
+
+  // Perform any post-deregistration cleanup tasks associated with the
+  // descriptor data.
+  BOOST_ASIO_DECL void cleanup_descriptor_data(
+      per_descriptor_data& descriptor_data);
+
+  // Add a new timer queue to the reactor.
+  template <typename Time_Traits>
+  void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
+
+  // Remove a timer queue from the reactor.
+  template <typename Time_Traits>
+  void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
+
+  // Schedule a new operation in the given timer queue to expire at the
+  // specified absolute time.
+  template <typename Time_Traits>
+  void schedule_timer(timer_queue<Time_Traits>& queue,
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
+
+  // Cancel the timer operations associated with the given token. Returns the
+  // number of operations that have been posted or dispatched.
+  template <typename Time_Traits>
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer,
+      std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
+
+  // Move the timer operations associated with the given timer.
+  template <typename Time_Traits>
+  void move_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& target,
+      typename timer_queue<Time_Traits>::per_timer_data& source);
+
+  // Run epoll once until interrupted or events are ready to be dispatched.
+  BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
+
+  // Interrupt the select loop.
+  BOOST_ASIO_DECL void interrupt();
+
+private:
+  // The hint to pass to epoll_create to size its data structures.
+  enum { epoll_size = 20000 };
+
+  // Create the epoll file descriptor. Throws an exception if the descriptor
+  // cannot be created.
+  BOOST_ASIO_DECL static int do_epoll_create();
+
+  // Create the timerfd file descriptor. Does not throw.
+  BOOST_ASIO_DECL static int do_timerfd_create();
+
+  // Allocate a new descriptor state object.
+  BOOST_ASIO_DECL descriptor_state* allocate_descriptor_state();
+
+  // Free an existing descriptor state object.
+  BOOST_ASIO_DECL void free_descriptor_state(descriptor_state* s);
+
+  // Helper function to add a new timer queue.
+  BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+  // Helper function to remove a timer queue.
+  BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
+
+  // Called to recalculate and update the timeout.
+  BOOST_ASIO_DECL void update_timeout();
+
+  // Get the timeout value for the epoll_wait call. The timeout value is
+  // returned as a number of milliseconds. A return value of -1 indicates
+  // that epoll_wait should block indefinitely.
+  BOOST_ASIO_DECL int get_timeout(int msec);
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+  // Get the timeout value for the timer descriptor. The return value is the
+  // flag argument to be used when calling timerfd_settime.
+  BOOST_ASIO_DECL int get_timeout(itimerspec& ts);
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+  // The scheduler implementation used to post completions.
+  scheduler& scheduler_;
+
+  // Mutex to protect access to internal data.
+  mutex mutex_;
+
+  // The interrupter is used to break a blocking epoll_wait call.
+  select_interrupter interrupter_;
+
+  // The epoll file descriptor.
+  int epoll_fd_;
+
+  // The timer file descriptor.
+  int timer_fd_;
+
+  // The timer queues.
+  timer_queue_set timer_queues_;
+
+  // Whether the service has been shut down.
+  bool shutdown_;
+
+  // Mutex to protect access to the registered descriptors.
+  mutex registered_descriptors_mutex_;
+
+  // Keep track of all registered descriptors.
+  object_pool<descriptor_state> registered_descriptors_;
+
+  // Helper class to do post-perform_io cleanup.
+  struct perform_io_cleanup_on_block_exit;
+  friend struct perform_io_cleanup_on_block_exit;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/impl/epoll_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/epoll_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP

+ 50 - 0
cpir-read/boost/boost/asio/detail/event.hpp

@@ -0,0 +1,50 @@
+//
+// detail/event.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_EVENT_HPP
+#define BOOST_ASIO_DETAIL_EVENT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_THREADS)
+# include <boost/asio/detail/null_event.hpp>
+#elif defined(BOOST_ASIO_WINDOWS)
+# include <boost/asio/detail/win_event.hpp>
+#elif defined(BOOST_ASIO_HAS_PTHREADS)
+# include <boost/asio/detail/posix_event.hpp>
+#elif defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
+# include <boost/asio/detail/std_event.hpp>
+#else
+# error Only Windows, POSIX and std::condition_variable are supported!
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if !defined(BOOST_ASIO_HAS_THREADS)
+typedef null_event event;
+#elif defined(BOOST_ASIO_WINDOWS)
+typedef win_event event;
+#elif defined(BOOST_ASIO_HAS_PTHREADS)
+typedef posix_event event;
+#elif defined(BOOST_ASIO_HAS_STD_MUTEX_AND_CONDVAR)
+typedef std_event event;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_EVENT_HPP

+ 85 - 0
cpir-read/boost/boost/asio/detail/eventfd_select_interrupter.hpp

@@ -0,0 +1,85 @@
+//
+// detail/eventfd_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP
+#define BOOST_ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EVENTFD)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class eventfd_select_interrupter
+{
+public:
+  // Constructor.
+  BOOST_ASIO_DECL eventfd_select_interrupter();
+
+  // Destructor.
+  BOOST_ASIO_DECL ~eventfd_select_interrupter();
+
+  // Recreate the interrupter's descriptors. Used after a fork.
+  BOOST_ASIO_DECL void recreate();
+
+  // Interrupt the select call.
+  BOOST_ASIO_DECL void interrupt();
+
+  // Reset the select interrupt. Returns true if the call was interrupted.
+  BOOST_ASIO_DECL bool reset();
+
+  // Get the read descriptor to be passed to select.
+  int read_descriptor() const
+  {
+    return read_descriptor_;
+  }
+
+private:
+  // Open the descriptors. Throws on error.
+  BOOST_ASIO_DECL void open_descriptors();
+
+  // Close the descriptors.
+  BOOST_ASIO_DECL void close_descriptors();
+
+  // The read end of a connection used to interrupt the select call. This file
+  // descriptor is passed to select such that when it is time to stop, a single
+  // 64bit value will be written on the other end of the connection and this
+  // descriptor will become readable.
+  int read_descriptor_;
+
+  // The write end of a connection used to interrupt the select call. A single
+  // 64bit non-zero value may be written to this to wake up the select which is
+  // waiting for the other end to become readable. This descriptor will only
+  // differ from the read descriptor when a pipe is used.
+  int write_descriptor_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/eventfd_select_interrupter.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_EVENTFD)
+
+#endif // BOOST_ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP

+ 86 - 0
cpir-read/boost/boost/asio/detail/executor_op.hpp

@@ -0,0 +1,86 @@
+//
+// detail/executor_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_EXECUTOR_OP_HPP
+#define BOOST_ASIO_DETAIL_EXECUTOR_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/scheduler_operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler, typename Alloc,
+    typename Operation = scheduler_operation>
+class executor_op : public Operation
+{
+public:
+  BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(executor_op);
+
+  template <typename H>
+  executor_op(BOOST_ASIO_MOVE_ARG(H) h, const Alloc& allocator)
+    : Operation(&executor_op::do_complete),
+      handler_(BOOST_ASIO_MOVE_CAST(H)(h)),
+      allocator_(allocator)
+  {
+  }
+
+  static void do_complete(void* owner, Operation* base,
+      const boost::system::error_code& /*ec*/,
+      std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    executor_op* o(static_cast<executor_op*>(base));
+    Alloc allocator(o->allocator_);
+    ptr p = { detail::addressof(allocator), o, o };
+
+    BOOST_ASIO_HANDLER_COMPLETION((*o));
+
+    // Make a copy of the handler so that the memory can be deallocated before
+    // the upcall is made. Even if we're not about to make an upcall, a
+    // sub-object of the handler may be the true owner of the memory associated
+    // with the handler. Consequently, a local copy of the handler is required
+    // to ensure that any owning sub-object remains valid until after we have
+    // deallocated the memory here.
+    Handler handler(BOOST_ASIO_MOVE_CAST(Handler)(o->handler_));
+    p.reset();
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      fenced_block b(fenced_block::half);
+      BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
+      boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      BOOST_ASIO_HANDLER_INVOCATION_END;
+    }
+  }
+
+private:
+  Handler handler_;
+  Alloc allocator_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_EXECUTOR_OP_HPP

+ 41 - 0
cpir-read/boost/boost/asio/detail/fd_set_adapter.hpp

@@ -0,0 +1,41 @@
+//
+// detail/fd_set_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP
+#define BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <boost/asio/detail/posix_fd_set_adapter.hpp>
+#include <boost/asio/detail/win_fd_set_adapter.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+typedef win_fd_set_adapter fd_set_adapter;
+#else
+typedef posix_fd_set_adapter fd_set_adapter;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP

+ 82 - 0
cpir-read/boost/boost/asio/detail/fenced_block.hpp

@@ -0,0 +1,82 @@
+//
+// detail/fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_THREADS) \
+  || defined(BOOST_ASIO_DISABLE_FENCED_BLOCK)
+# include <boost/asio/detail/null_fenced_block.hpp>
+#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
+# include <boost/asio/detail/std_fenced_block.hpp>
+#elif defined(__MACH__) && defined(__APPLE__)
+# include <boost/asio/detail/macos_fenced_block.hpp>
+#elif defined(__sun)
+# include <boost/asio/detail/solaris_fenced_block.hpp>
+#elif defined(__GNUC__) && defined(__arm__) \
+  && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+# include <boost/asio/detail/gcc_arm_fenced_block.hpp>
+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
+# include <boost/asio/detail/gcc_hppa_fenced_block.hpp>
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# include <boost/asio/detail/gcc_x86_fenced_block.hpp>
+#elif defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+# include <boost/asio/detail/gcc_sync_fenced_block.hpp>
+#elif defined(BOOST_ASIO_WINDOWS) && !defined(UNDER_CE)
+# include <boost/asio/detail/win_fenced_block.hpp>
+#else
+# include <boost/asio/detail/null_fenced_block.hpp>
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if !defined(BOOST_ASIO_HAS_THREADS) \
+  || defined(BOOST_ASIO_DISABLE_FENCED_BLOCK)
+typedef null_fenced_block fenced_block;
+#elif defined(BOOST_ASIO_HAS_STD_ATOMIC)
+typedef std_fenced_block fenced_block;
+#elif defined(__MACH__) && defined(__APPLE__)
+typedef macos_fenced_block fenced_block;
+#elif defined(__sun)
+typedef solaris_fenced_block fenced_block;
+#elif defined(__GNUC__) && defined(__arm__) \
+  && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+typedef gcc_arm_fenced_block fenced_block;
+#elif defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
+typedef gcc_hppa_fenced_block fenced_block;
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+typedef gcc_x86_fenced_block fenced_block;
+#elif defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+typedef gcc_sync_fenced_block fenced_block;
+#elif defined(BOOST_ASIO_WINDOWS) && !defined(UNDER_CE)
+typedef win_fenced_block fenced_block;
+#else
+typedef null_fenced_block fenced_block;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP

+ 40 - 0
cpir-read/boost/boost/asio/detail/functional.hpp

@@ -0,0 +1,40 @@
+//
+// detail/functional.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_FUNCTIONAL_HPP
+#define BOOST_ASIO_DETAIL_FUNCTIONAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#include <functional>
+
+#if !defined(BOOST_ASIO_HAS_STD_FUNCTION)
+# include <boost/function.hpp>
+#endif // !defined(BOOST_ASIO_HAS_STD_FUNCTION)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_HAS_STD_FUNCTION)
+using std::function;
+#else // defined(BOOST_ASIO_HAS_STD_FUNCTION)
+using boost::function;
+#endif // defined(BOOST_ASIO_HAS_STD_FUNCTION)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_FUNCTIONAL_HPP

+ 93 - 0
cpir-read/boost/boost/asio/detail/gcc_arm_fenced_block.hpp

@@ -0,0 +1,93 @@
+//
+// detail/gcc_arm_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(__GNUC__) && defined(__arm__)
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_arm_fenced_block
+  : private noncopyable
+{
+public:
+  enum half_t { half };
+  enum full_t { full };
+
+  // Constructor for a half fenced block.
+  explicit gcc_arm_fenced_block(half_t)
+  {
+  }
+
+  // Constructor for a full fenced block.
+  explicit gcc_arm_fenced_block(full_t)
+  {
+    barrier();
+  }
+
+  // Destructor.
+  ~gcc_arm_fenced_block()
+  {
+    barrier();
+  }
+
+private:
+  static void barrier()
+  {
+#if defined(__ARM_ARCH_4__) \
+    || defined(__ARM_ARCH_4T__) \
+    || defined(__ARM_ARCH_5__) \
+    || defined(__ARM_ARCH_5E__) \
+    || defined(__ARM_ARCH_5T__) \
+    || defined(__ARM_ARCH_5TE__) \
+    || defined(__ARM_ARCH_5TEJ__) \
+    || defined(__ARM_ARCH_6__) \
+    || defined(__ARM_ARCH_6J__) \
+    || defined(__ARM_ARCH_6K__) \
+    || defined(__ARM_ARCH_6Z__) \
+    || defined(__ARM_ARCH_6ZK__) \
+    || defined(__ARM_ARCH_6T2__)
+# if defined(__thumb__)
+    // This is just a placeholder and almost certainly not sufficient.
+    __asm__ __volatile__ ("" : : : "memory");
+# else // defined(__thumb__)
+    int a = 0, b = 0;
+    __asm__ __volatile__ ("swp %0, %1, [%2]"
+        : "=&r"(a) : "r"(1), "r"(&b) : "memory", "cc");
+# endif // defined(__thumb__)
+#else
+    // ARMv7 and later.
+    __asm__ __volatile__ ("dmb" : : : "memory");
+#endif
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(__GNUC__) && defined(__arm__)
+
+#endif // BOOST_ASIO_DETAIL_GCC_ARM_FENCED_BLOCK_HPP

+ 70 - 0
cpir-read/boost/boost/asio/detail/gcc_hppa_fenced_block.hpp

@@ -0,0 +1,70 @@
+//
+// detail/gcc_hppa_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_hppa_fenced_block
+  : private noncopyable
+{
+public:
+  enum half_t { half };
+  enum full_t { full };
+
+  // Constructor for a half fenced block.
+  explicit gcc_hppa_fenced_block(half_t)
+  {
+  }
+
+  // Constructor for a full fenced block.
+  explicit gcc_hppa_fenced_block(full_t)
+  {
+    barrier();
+  }
+
+  // Destructor.
+  ~gcc_hppa_fenced_block()
+  {
+    barrier();
+  }
+
+private:
+  static void barrier()
+  {
+    // This is just a placeholder and almost certainly not sufficient.
+    __asm__ __volatile__ ("" : : : "memory");
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(__GNUC__) && (defined(__hppa) || defined(__hppa__))
+
+#endif // BOOST_ASIO_DETAIL_GCC_HPPA_FENCED_BLOCK_HPP

+ 67 - 0
cpir-read/boost/boost/asio/detail/gcc_sync_fenced_block.hpp

@@ -0,0 +1,67 @@
+//
+// detail/gcc_sync_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
+  && !defined(__INTEL_COMPILER) && !defined(__ICL) \
+  && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_sync_fenced_block
+  : private noncopyable
+{
+public:
+  enum half_or_full_t { half, full };
+
+  // Constructor.
+  explicit gcc_sync_fenced_block(half_or_full_t)
+    : value_(0)
+  {
+    __sync_lock_test_and_set(&value_, 1);
+  }
+
+  // Destructor.
+  ~gcc_sync_fenced_block()
+  {
+    __sync_lock_release(&value_);
+  }
+
+private:
+  int value_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(__GNUC__)
+       // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+       // && !defined(__INTEL_COMPILER) && !defined(__ICL)
+       // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
+
+#endif // BOOST_ASIO_DETAIL_GCC_SYNC_FENCED_BLOCK_HPP

+ 101 - 0
cpir-read/boost/boost/asio/detail/gcc_x86_fenced_block.hpp

@@ -0,0 +1,101 @@
+//
+// detail/gcc_x86_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_x86_fenced_block
+  : private noncopyable
+{
+public:
+  enum half_t { half };
+  enum full_t { full };
+
+  // Constructor for a half fenced block.
+  explicit gcc_x86_fenced_block(half_t)
+  {
+  }
+
+  // Constructor for a full fenced block.
+  explicit gcc_x86_fenced_block(full_t)
+  {
+    lbarrier();
+  }
+
+  // Destructor.
+  ~gcc_x86_fenced_block()
+  {
+    sbarrier();
+  }
+
+private:
+  static int barrier()
+  {
+    int r = 0, m = 1;
+    __asm__ __volatile__ (
+        "xchgl %0, %1" :
+        "=r"(r), "=m"(m) :
+        "0"(1), "m"(m) :
+        "memory", "cc");
+    return r;
+  }
+
+  static void lbarrier()
+  {
+#if defined(__SSE2__)
+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+    __builtin_ia32_lfence();
+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+    __asm__ __volatile__ ("lfence" ::: "memory");
+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+#else // defined(__SSE2__)
+    barrier();
+#endif // defined(__SSE2__)
+  }
+
+  static void sbarrier()
+  {
+#if defined(__SSE2__)
+# if (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+    __builtin_ia32_sfence();
+# else // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+    __asm__ __volatile__ ("sfence" ::: "memory");
+# endif // (__GNUC__ >= 4) && !defined(__INTEL_COMPILER) && !defined(__ICL)
+#else // defined(__SSE2__)
+    barrier();
+#endif // defined(__SSE2__)
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+#endif // BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP

+ 54 - 0
cpir-read/boost/boost/asio/detail/global.hpp

@@ -0,0 +1,54 @@
+//
+// detail/global.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_GLOBAL_HPP
+#define BOOST_ASIO_DETAIL_GLOBAL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_THREADS)
+# include <boost/asio/detail/null_global.hpp>
+#elif defined(BOOST_ASIO_WINDOWS)
+# include <boost/asio/detail/win_global.hpp>
+#elif defined(BOOST_ASIO_HAS_PTHREADS)
+# include <boost/asio/detail/posix_global.hpp>
+#elif defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
+# include <boost/asio/detail/std_global.hpp>
+#else
+# error Only Windows, POSIX and std::call_once are supported!
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+inline T& global()
+{
+#if !defined(BOOST_ASIO_HAS_THREADS)
+  return null_global<T>();
+#elif defined(BOOST_ASIO_WINDOWS)
+  return win_global<T>();
+#elif defined(BOOST_ASIO_HAS_PTHREADS)
+  return posix_global<T>();
+#elif defined(BOOST_ASIO_HAS_STD_CALL_ONCE)
+  return std_global<T>();
+#endif
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_GLOBAL_HPP

+ 237 - 0
cpir-read/boost/boost/asio/detail/handler_alloc_helpers.hpp

@@ -0,0 +1,237 @@
+//
+// detail/handler_alloc_helpers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/recycling_allocator.hpp>
+#include <boost/asio/associated_allocator.hpp>
+#include <boost/asio/handler_alloc_hook.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+// Calls to asio_handler_allocate and asio_handler_deallocate must be made from
+// a namespace that does not contain any overloads of these functions. The
+// boost_asio_handler_alloc_helpers namespace is defined here for that purpose.
+namespace boost_asio_handler_alloc_helpers {
+
+template <typename Handler>
+inline void* allocate(std::size_t s, Handler& h)
+{
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+  return ::operator new(s);
+#else
+  using boost::asio::asio_handler_allocate;
+  return asio_handler_allocate(s, boost::asio::detail::addressof(h));
+#endif
+}
+
+template <typename Handler>
+inline void deallocate(void* p, std::size_t s, Handler& h)
+{
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+  ::operator delete(p);
+#else
+  using boost::asio::asio_handler_deallocate;
+  asio_handler_deallocate(p, s, boost::asio::detail::addressof(h));
+#endif
+}
+
+} // namespace boost_asio_handler_alloc_helpers
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler, typename T>
+class hook_allocator
+{
+public:
+  typedef T value_type;
+
+  template <typename U>
+  struct rebind
+  {
+    typedef hook_allocator<Handler, U> other;
+  };
+
+  explicit hook_allocator(Handler& h)
+    : handler_(h)
+  {
+  }
+
+  template <typename U>
+  hook_allocator(const hook_allocator<Handler, U>& a)
+    : handler_(a.handler_)
+  {
+  }
+
+  T* allocate(std::size_t n)
+  {
+    return static_cast<T*>(
+        boost_asio_handler_alloc_helpers::allocate(sizeof(T) * n, handler_));
+  }
+
+  void deallocate(T* p, std::size_t n)
+  {
+    boost_asio_handler_alloc_helpers::deallocate(p, sizeof(T) * n, handler_);
+  }
+
+//private:
+  Handler& handler_;
+};
+
+template <typename Handler>
+class hook_allocator<Handler, void>
+{
+public:
+  typedef void value_type;
+
+  template <typename U>
+  struct rebind
+  {
+    typedef hook_allocator<Handler, U> other;
+  };
+
+  explicit hook_allocator(Handler& h)
+    : handler_(h)
+  {
+  }
+
+  template <typename U>
+  hook_allocator(const hook_allocator<Handler, U>& a)
+    : handler_(a.handler_)
+  {
+  }
+
+//private:
+  Handler& handler_;
+};
+
+template <typename Handler, typename Allocator>
+struct get_hook_allocator
+{
+  typedef Allocator type;
+
+  static type get(Handler&, const Allocator& a)
+  {
+    return a;
+  }
+};
+
+template <typename Handler, typename T>
+struct get_hook_allocator<Handler, std::allocator<T> >
+{
+  typedef hook_allocator<Handler, T> type;
+
+  static type get(Handler& handler, const std::allocator<T>&)
+  {
+    return type(handler);
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#define BOOST_ASIO_DEFINE_HANDLER_PTR(op) \
+  struct ptr \
+  { \
+    Handler* h; \
+    op* v; \
+    op* p; \
+    ~ptr() \
+    { \
+      reset(); \
+    } \
+    static op* allocate(Handler& handler) \
+    { \
+      typedef typename ::boost::asio::associated_allocator< \
+        Handler>::type associated_allocator_type; \
+      typedef typename ::boost::asio::detail::get_hook_allocator< \
+        Handler, associated_allocator_type>::type hook_allocator_type; \
+      BOOST_ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
+            ::boost::asio::detail::get_hook_allocator< \
+              Handler, associated_allocator_type>::get( \
+                handler, ::boost::asio::get_associated_allocator(handler))); \
+      return a.allocate(1); \
+    } \
+    void reset() \
+    { \
+      if (p) \
+      { \
+        p->~op(); \
+        p = 0; \
+      } \
+      if (v) \
+      { \
+        typedef typename ::boost::asio::associated_allocator< \
+          Handler>::type associated_allocator_type; \
+        typedef typename ::boost::asio::detail::get_hook_allocator< \
+          Handler, associated_allocator_type>::type hook_allocator_type; \
+        BOOST_ASIO_REBIND_ALLOC(hook_allocator_type, op) a( \
+              ::boost::asio::detail::get_hook_allocator< \
+                Handler, associated_allocator_type>::get( \
+                  *h, ::boost::asio::get_associated_allocator(*h))); \
+        a.deallocate(static_cast<op*>(v), 1); \
+        v = 0; \
+      } \
+    } \
+  } \
+  /**/
+
+#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
+  struct ptr \
+  { \
+    const Alloc* a; \
+    void* v; \
+    op* p; \
+    ~ptr() \
+    { \
+      reset(); \
+    } \
+    static op* allocate(const Alloc& a) \
+    { \
+      typedef typename ::boost::asio::detail::get_recycling_allocator< \
+        Alloc>::type recycling_allocator_type; \
+      BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
+            ::boost::asio::detail::get_recycling_allocator<Alloc>::get(a)); \
+      return a1.allocate(1); \
+    } \
+    void reset() \
+    { \
+      if (p) \
+      { \
+        p->~op(); \
+        p = 0; \
+      } \
+      if (v) \
+      { \
+        typedef typename ::boost::asio::detail::get_recycling_allocator< \
+          Alloc>::type recycling_allocator_type; \
+        BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
+              ::boost::asio::detail::get_recycling_allocator<Alloc>::get(*a)); \
+        a1.deallocate(static_cast<op*>(v), 1); \
+        v = 0; \
+      } \
+    } \
+  } \
+  /**/
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP

+ 45 - 0
cpir-read/boost/boost/asio/detail/handler_cont_helpers.hpp

@@ -0,0 +1,45 @@
+//
+// detail/handler_cont_helpers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/handler_continuation_hook.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+// Calls to asio_handler_is_continuation must be made from a namespace that
+// does not contain overloads of this function. This namespace is defined here
+// for that purpose.
+namespace boost_asio_handler_cont_helpers {
+
+template <typename Context>
+inline bool is_continuation(Context& context)
+{
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+  return false;
+#else
+  using boost::asio::asio_handler_is_continuation;
+  return asio_handler_is_continuation(
+      boost::asio::detail::addressof(context));
+#endif
+}
+
+} // namespace boost_asio_handler_cont_helpers
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_CONT_HELPERS_HPP

+ 57 - 0
cpir-read/boost/boost/asio/detail/handler_invoke_helpers.hpp

@@ -0,0 +1,57 @@
+//
+// detail/handler_invoke_helpers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/handler_invoke_hook.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+// Calls to asio_handler_invoke must be made from a namespace that does not
+// contain overloads of this function. The boost_asio_handler_invoke_helpers
+// namespace is defined here for that purpose.
+namespace boost_asio_handler_invoke_helpers {
+
+template <typename Function, typename Context>
+inline void invoke(Function& function, Context& context)
+{
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+  Function tmp(function);
+  tmp();
+#else
+  using boost::asio::asio_handler_invoke;
+  asio_handler_invoke(function, boost::asio::detail::addressof(context));
+#endif
+}
+
+template <typename Function, typename Context>
+inline void invoke(const Function& function, Context& context)
+{
+#if !defined(BOOST_ASIO_HAS_HANDLER_HOOKS)
+  Function tmp(function);
+  tmp();
+#else
+  using boost::asio::asio_handler_invoke;
+  asio_handler_invoke(function, boost::asio::detail::addressof(context));
+#endif
+}
+
+} // namespace boost_asio_handler_invoke_helpers
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_INVOKE_HELPERS_HPP

+ 242 - 0
cpir-read/boost/boost/asio/detail/handler_tracking.hpp

@@ -0,0 +1,242 @@
+//
+// detail/handler_tracking.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+namespace boost {
+namespace asio {
+
+class execution_context;
+
+} // namespace asio
+} // namespace boost
+
+#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
+# include BOOST_ASIO_CUSTOM_HANDLER_TRACKING
+#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+# include <boost/system/error_code.hpp>
+# include <boost/asio/detail/cstdint.hpp>
+# include <boost/asio/detail/static_mutex.hpp>
+# include <boost/asio/detail/tss_ptr.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
+
+// The user-specified header must define the following macros:
+// - BOOST_ASIO_INHERIT_TRACKED_HANDLER
+// - BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER
+// - BOOST_ASIO_HANDLER_TRACKING_INIT
+// - BOOST_ASIO_HANDLER_CREATION(args)
+// - BOOST_ASIO_HANDLER_COMPLETION(args)
+// - BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args)
+// - BOOST_ASIO_HANDLER_INVOCATION_END
+// - BOOST_ASIO_HANDLER_OPERATION(args)
+// - BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args)
+// - BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args)
+// - BOOST_ASIO_HANDLER_REACTOR_READ_EVENT
+// - BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT
+// - BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT
+// - BOOST_ASIO_HANDLER_REACTOR_EVENTS(args)
+// - BOOST_ASIO_HANDLER_REACTOR_OPERATION(args)
+
+# if !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+#  define BOOST_ASIO_ENABLE_HANDLER_TRACKING 1
+# endif /// !defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+class handler_tracking
+{
+public:
+  class completion;
+
+  // Base class for objects containing tracked handlers.
+  class tracked_handler
+  {
+  private:
+    // Only the handler_tracking class will have access to the id.
+    friend class handler_tracking;
+    friend class completion;
+    uint64_t id_;
+
+  protected:
+    // Constructor initialises with no id.
+    tracked_handler() : id_(0) {}
+
+    // Prevent deletion through this type.
+    ~tracked_handler() {}
+  };
+
+  // Initialise the tracking system.
+  BOOST_ASIO_DECL static void init();
+
+  // Record the creation of a tracked handler.
+  BOOST_ASIO_DECL static void creation(
+      execution_context& context, tracked_handler& h,
+      const char* object_type, void* object,
+      uintmax_t native_handle, const char* op_name);
+
+  class completion
+  {
+  public:
+    // Constructor records that handler is to be invoked with no arguments.
+    BOOST_ASIO_DECL explicit completion(const tracked_handler& h);
+
+    // Destructor records only when an exception is thrown from the handler, or
+    // if the memory is being freed without the handler having been invoked.
+    BOOST_ASIO_DECL ~completion();
+
+    // Records that handler is to be invoked with no arguments.
+    BOOST_ASIO_DECL void invocation_begin();
+
+    // Records that handler is to be invoked with one arguments.
+    BOOST_ASIO_DECL void invocation_begin(const boost::system::error_code& ec);
+
+    // Constructor records that handler is to be invoked with two arguments.
+    BOOST_ASIO_DECL void invocation_begin(
+        const boost::system::error_code& ec, std::size_t bytes_transferred);
+
+    // Constructor records that handler is to be invoked with two arguments.
+    BOOST_ASIO_DECL void invocation_begin(
+        const boost::system::error_code& ec, int signal_number);
+
+    // Constructor records that handler is to be invoked with two arguments.
+    BOOST_ASIO_DECL void invocation_begin(
+        const boost::system::error_code& ec, const char* arg);
+
+    // Record that handler invocation has ended.
+    BOOST_ASIO_DECL void invocation_end();
+
+  private:
+    friend class handler_tracking;
+    uint64_t id_;
+    bool invoked_;
+    completion* next_;
+  };
+
+  // Record an operation that is not directly associated with a handler.
+  BOOST_ASIO_DECL static void operation(execution_context& context,
+      const char* object_type, void* object,
+      uintmax_t native_handle, const char* op_name);
+
+  // Record that a descriptor has been registered with the reactor.
+  BOOST_ASIO_DECL static void reactor_registration(execution_context& context,
+      uintmax_t native_handle, uintmax_t registration);
+
+  // Record that a descriptor has been deregistered from the reactor.
+  BOOST_ASIO_DECL static void reactor_deregistration(execution_context& context,
+      uintmax_t native_handle, uintmax_t registration);
+
+  // Record a reactor-based operation that is associated with a handler.
+  BOOST_ASIO_DECL static void reactor_events(execution_context& context,
+      uintmax_t registration, unsigned events);
+
+  // Record a reactor-based operation that is associated with a handler.
+  BOOST_ASIO_DECL static void reactor_operation(
+      const tracked_handler& h, const char* op_name,
+      const boost::system::error_code& ec);
+
+  // Record a reactor-based operation that is associated with a handler.
+  BOOST_ASIO_DECL static void reactor_operation(
+      const tracked_handler& h, const char* op_name,
+      const boost::system::error_code& ec, std::size_t bytes_transferred);
+
+  // Write a line of output.
+  BOOST_ASIO_DECL static void write_line(const char* format, ...);
+
+private:
+  struct tracking_state;
+  BOOST_ASIO_DECL static tracking_state* get_state();
+};
+
+# define BOOST_ASIO_INHERIT_TRACKED_HANDLER \
+  : public boost::asio::detail::handler_tracking::tracked_handler
+
+# define BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER \
+  , public boost::asio::detail::handler_tracking::tracked_handler
+
+# define BOOST_ASIO_HANDLER_TRACKING_INIT \
+  boost::asio::detail::handler_tracking::init()
+
+# define BOOST_ASIO_HANDLER_CREATION(args) \
+  boost::asio::detail::handler_tracking::creation args
+
+# define BOOST_ASIO_HANDLER_COMPLETION(args) \
+  boost::asio::detail::handler_tracking::completion tracked_completion args
+
+# define BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) \
+  tracked_completion.invocation_begin args
+
+# define BOOST_ASIO_HANDLER_INVOCATION_END \
+  tracked_completion.invocation_end()
+
+# define BOOST_ASIO_HANDLER_OPERATION(args) \
+  boost::asio::detail::handler_tracking::operation args
+
+# define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) \
+  boost::asio::detail::handler_tracking::reactor_registration args
+
+# define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) \
+  boost::asio::detail::handler_tracking::reactor_deregistration args
+
+# define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 1
+# define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 2
+# define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 4
+
+# define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) \
+  boost::asio::detail::handler_tracking::reactor_events args
+
+# define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) \
+  boost::asio::detail::handler_tracking::reactor_operation args
+
+#else // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+# define BOOST_ASIO_INHERIT_TRACKED_HANDLER
+# define BOOST_ASIO_ALSO_INHERIT_TRACKED_HANDLER
+# define BOOST_ASIO_HANDLER_TRACKING_INIT (void)0
+# define BOOST_ASIO_HANDLER_CREATION(args) (void)0
+# define BOOST_ASIO_HANDLER_COMPLETION(args) (void)0
+# define BOOST_ASIO_HANDLER_INVOCATION_BEGIN(args) (void)0
+# define BOOST_ASIO_HANDLER_INVOCATION_END (void)0
+# define BOOST_ASIO_HANDLER_OPERATION(args) (void)0
+# define BOOST_ASIO_HANDLER_REACTOR_REGISTRATION(args) (void)0
+# define BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION(args) (void)0
+# define BOOST_ASIO_HANDLER_REACTOR_READ_EVENT 0
+# define BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT 0
+# define BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT 0
+# define BOOST_ASIO_HANDLER_REACTOR_EVENTS(args) (void)0
+# define BOOST_ASIO_HANDLER_REACTOR_OPERATION(args) (void)0
+
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/handler_tracking.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_TRACKING_HPP

+ 558 - 0
cpir-read/boost/boost/asio/detail/handler_type_requirements.hpp

@@ -0,0 +1,558 @@
+//
+// detail/handler_type_requirements.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+// Older versions of gcc have difficulty compiling the sizeof expressions where
+// we test the handler type requirements. We'll disable checking of handler type
+// requirements for those compilers, but otherwise enable it by default.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+# if !defined(__GNUC__) || (__GNUC__ >= 4)
+#  define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1
+# endif // !defined(__GNUC__) || (__GNUC__ >= 4)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+// With C++0x we can use a combination of enhanced SFINAE and static_assert to
+// generate better template error messages. As this technique is not yet widely
+// portable, we'll only enable it for tested compilers.
+#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+# if defined(__GNUC__)
+#  if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+#   if defined(__GXX_EXPERIMENTAL_CXX0X__)
+#    define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+#   endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
+#  endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
+# endif // defined(__GNUC__)
+# if defined(BOOST_ASIO_MSVC)
+#  if (_MSC_VER >= 1600)
+#   define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+#  endif // (_MSC_VER >= 1600)
+# endif // defined(BOOST_ASIO_MSVC)
+# if defined(__clang__)
+#  if __has_feature(__cxx_static_assert__)
+#   define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1
+#  endif // __has_feature(cxx_static_assert)
+# endif // defined(__clang__)
+#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+# include <boost/asio/async_result.hpp>
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename Handler>
+auto zero_arg_copyable_handler_test(Handler h, void*)
+  -> decltype(
+    sizeof(Handler(static_cast<const Handler&>(h))),
+    ((h)()),
+    char(0));
+
+template <typename Handler>
+char (&zero_arg_copyable_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1>
+auto one_arg_handler_test(Handler h, Arg1* a1)
+  -> decltype(
+    sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+    ((h)(*a1)),
+    char(0));
+
+template <typename Handler>
+char (&one_arg_handler_test(Handler h, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2)
+  -> decltype(
+    sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+    ((h)(*a1, *a2)),
+    char(0));
+
+template <typename Handler>
+char (&two_arg_handler_test(Handler, ...))[2];
+
+template <typename Handler, typename Arg1, typename Arg2>
+auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2)
+  -> decltype(
+    sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))),
+    ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))),
+    char(0));
+
+template <typename Handler>
+char (&two_arg_move_handler_test(Handler, ...))[2];
+
+#  define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \
+     static_assert(expr, msg);
+
+# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+#  define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg)
+
+# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT)
+
+template <typename T> T& lvref();
+template <typename T> T& lvref(T);
+template <typename T> const T& clvref();
+template <typename T> const T& clvref(T);
+#if defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> T rvref();
+template <typename T> T rvref(T);
+#else // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> const T& rvref();
+template <typename T> const T& rvref(T);
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+template <typename T> char argbyv(T);
+
+template <int>
+struct handler_type_requirements
+{
+};
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void()) asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \
+          boost::asio::detail::clvref< \
+            asio_true_handler_type>(), 0)) == 1, \
+      "CompletionHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::clvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()(), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, std::size_t)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const std::size_t*>(0))) == 1, \
+      "ReadHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const std::size_t>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, std::size_t)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const std::size_t*>(0))) == 1, \
+      "WriteHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const std::size_t>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::one_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0))) == 1, \
+      "AcceptHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+    handler_type, handler, socket_type) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, socket_type)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_move_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<socket_type*>(0))) == 1, \
+      "MoveAcceptHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::rvref<socket_type>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::one_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0))) == 1, \
+      "ConnectHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+    handler_type, handler, endpoint_type) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, endpoint_type)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const endpoint_type*>(0))) == 1, \
+      "RangeConnectHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const endpoint_type>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+    handler_type, handler, iter_type) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, iter_type)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const iter_type*>(0))) == 1, \
+      "IteratorConnectHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const iter_type>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+    handler_type, handler, range_type) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, range_type)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const range_type*>(0))) == 1, \
+      "ResolveHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const range_type>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::one_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0))) == 1, \
+      "WaitHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, int)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const int*>(0))) == 1, \
+      "SignalHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>(), \
+            boost::asio::detail::lvref<const int>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::one_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0))) == 1, \
+      "HandshakeHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code, std::size_t)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::two_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0), \
+          static_cast<const std::size_t*>(0))) == 1, \
+      "BufferedHandshakeHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+          boost::asio::detail::lvref<const boost::system::error_code>(), \
+          boost::asio::detail::lvref<const std::size_t>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+    handler_type, handler) \
+  \
+  typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \
+      void(boost::system::error_code)) \
+    asio_true_handler_type; \
+  \
+  BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
+      sizeof(boost::asio::detail::one_arg_handler_test( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>(), \
+          static_cast<const boost::system::error_code*>(0))) == 1, \
+      "ShutdownHandler type requirements not met") \
+  \
+  typedef boost::asio::detail::handler_type_requirements< \
+      sizeof( \
+        boost::asio::detail::argbyv( \
+          boost::asio::detail::rvref< \
+            asio_true_handler_type>())) + \
+      sizeof( \
+        boost::asio::detail::lvref< \
+          asio_true_handler_type>()( \
+            boost::asio::detail::lvref<const boost::system::error_code>()), \
+        char(0))> BOOST_ASIO_UNUSED_TYPEDEF
+
+#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_READ_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WRITE_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \
+    handler_type, handler, socket_type) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \
+    handler_type, handler, iter_type) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \
+    handler_type, handler, iter_type) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \
+    handler_type, handler, iter_type) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_WAIT_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \
+    handler_type, handler) \
+  typedef int BOOST_ASIO_UNUSED_TYPEDEF
+
+#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_HPP

+ 97 - 0
cpir-read/boost/boost/asio/detail/handler_work.hpp

@@ -0,0 +1,97 @@
+//
+// detail/handler_work.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HANDLER_WORK_HPP
+#define BOOST_ASIO_DETAIL_HANDLER_WORK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/associated_executor.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// A helper class template to allow completion handlers to be dispatched
+// through either the new executors framework or the old invocaton hook. The
+// primary template uses the new executors framework.
+template <typename Handler, typename Executor
+    = typename associated_executor<Handler>::type>
+class handler_work
+{
+public:
+  explicit handler_work(Handler& handler) BOOST_ASIO_NOEXCEPT
+    : executor_(associated_executor<Handler>::get(handler))
+  {
+  }
+
+  static void start(Handler& handler) BOOST_ASIO_NOEXCEPT
+  {
+    Executor ex(associated_executor<Handler>::get(handler));
+    ex.on_work_started();
+  }
+
+  ~handler_work()
+  {
+    executor_.on_work_finished();
+  }
+
+  template <typename Function>
+  void complete(Function& function, Handler& handler)
+  {
+    executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function),
+        associated_allocator<Handler>::get(handler));
+  }
+
+private:
+  // Disallow copying and assignment.
+  handler_work(const handler_work&);
+  handler_work& operator=(const handler_work&);
+
+  typename associated_executor<Handler>::type executor_;
+};
+
+// This specialisation dispatches a handler through the old invocation hook.
+// The specialisation is not strictly required for correctness, as the
+// system_executor will dispatch through the hook anyway. However, by doing
+// this we avoid an extra copy of the handler.
+template <typename Handler>
+class handler_work<Handler, system_executor>
+{
+public:
+  explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {}
+  static void start(Handler&) BOOST_ASIO_NOEXCEPT {}
+  ~handler_work() {}
+
+  template <typename Function>
+  void complete(Function& function, Handler& handler)
+  {
+    boost_asio_handler_invoke_helpers::invoke(function, handler);
+  }
+
+private:
+  // Disallow copying and assignment.
+  handler_work(const handler_work&);
+  handler_work& operator=(const handler_work&);
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HANDLER_WORK_HPP

+ 333 - 0
cpir-read/boost/boost/asio/detail/hash_map.hpp

@@ -0,0 +1,333 @@
+//
+// detail/hash_map.hpp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_HASH_MAP_HPP
+#define BOOST_ASIO_DETAIL_HASH_MAP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <list>
+#include <utility>
+#include <boost/asio/detail/assert.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# include <boost/asio/detail/socket_types.hpp>
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+inline std::size_t calculate_hash_value(int i)
+{
+  return static_cast<std::size_t>(i);
+}
+
+inline std::size_t calculate_hash_value(void* p)
+{
+  return reinterpret_cast<std::size_t>(p)
+    + (reinterpret_cast<std::size_t>(p) >> 3);
+}
+
+#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+inline std::size_t calculate_hash_value(SOCKET s)
+{
+  return static_cast<std::size_t>(s);
+}
+#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+
+// Note: assumes K and V are POD types.
+template <typename K, typename V>
+class hash_map
+  : private noncopyable
+{
+public:
+  // The type of a value in the map.
+  typedef std::pair<K, V> value_type;
+
+  // The type of a non-const iterator over the hash map.
+  typedef typename std::list<value_type>::iterator iterator;
+
+  // The type of a const iterator over the hash map.
+  typedef typename std::list<value_type>::const_iterator const_iterator;
+
+  // Constructor.
+  hash_map()
+    : size_(0),
+      buckets_(0),
+      num_buckets_(0)
+  {
+  }
+
+  // Destructor.
+  ~hash_map()
+  {
+    delete[] buckets_;
+  }
+
+  // Get an iterator for the beginning of the map.
+  iterator begin()
+  {
+    return values_.begin();
+  }
+
+  // Get an iterator for the beginning of the map.
+  const_iterator begin() const
+  {
+    return values_.begin();
+  }
+
+  // Get an iterator for the end of the map.
+  iterator end()
+  {
+    return values_.end();
+  }
+
+  // Get an iterator for the end of the map.
+  const_iterator end() const
+  {
+    return values_.end();
+  }
+
+  // Check whether the map is empty.
+  bool empty() const
+  {
+    return values_.empty();
+  }
+
+  // Find an entry in the map.
+  iterator find(const K& k)
+  {
+    if (num_buckets_)
+    {
+      size_t bucket = calculate_hash_value(k) % num_buckets_;
+      iterator it = buckets_[bucket].first;
+      if (it == values_.end())
+        return values_.end();
+      iterator end_it = buckets_[bucket].last;
+      ++end_it;
+      while (it != end_it)
+      {
+        if (it->first == k)
+          return it;
+        ++it;
+      }
+    }
+    return values_.end();
+  }
+
+  // Find an entry in the map.
+  const_iterator find(const K& k) const
+  {
+    if (num_buckets_)
+    {
+      size_t bucket = calculate_hash_value(k) % num_buckets_;
+      const_iterator it = buckets_[bucket].first;
+      if (it == values_.end())
+        return it;
+      const_iterator end_it = buckets_[bucket].last;
+      ++end_it;
+      while (it != end_it)
+      {
+        if (it->first == k)
+          return it;
+        ++it;
+      }
+    }
+    return values_.end();
+  }
+
+  // Insert a new entry into the map.
+  std::pair<iterator, bool> insert(const value_type& v)
+  {
+    if (size_ + 1 >= num_buckets_)
+      rehash(hash_size(size_ + 1));
+    size_t bucket = calculate_hash_value(v.first) % num_buckets_;
+    iterator it = buckets_[bucket].first;
+    if (it == values_.end())
+    {
+      buckets_[bucket].first = buckets_[bucket].last =
+        values_insert(values_.end(), v);
+      ++size_;
+      return std::pair<iterator, bool>(buckets_[bucket].last, true);
+    }
+    iterator end_it = buckets_[bucket].last;
+    ++end_it;
+    while (it != end_it)
+    {
+      if (it->first == v.first)
+        return std::pair<iterator, bool>(it, false);
+      ++it;
+    }
+    buckets_[bucket].last = values_insert(end_it, v);
+    ++size_;
+    return std::pair<iterator, bool>(buckets_[bucket].last, true);
+  }
+
+  // Erase an entry from the map.
+  void erase(iterator it)
+  {
+    BOOST_ASIO_ASSERT(it != values_.end());
+    BOOST_ASIO_ASSERT(num_buckets_ != 0);
+
+    size_t bucket = calculate_hash_value(it->first) % num_buckets_;
+    bool is_first = (it == buckets_[bucket].first);
+    bool is_last = (it == buckets_[bucket].last);
+    if (is_first && is_last)
+      buckets_[bucket].first = buckets_[bucket].last = values_.end();
+    else if (is_first)
+      ++buckets_[bucket].first;
+    else if (is_last)
+      --buckets_[bucket].last;
+
+    values_erase(it);
+    --size_;
+  }
+
+  // Erase a key from the map.
+  void erase(const K& k)
+  {
+    iterator it = find(k);
+    if (it != values_.end())
+      erase(it);
+  }
+
+  // Remove all entries from the map.
+  void clear()
+  {
+    // Clear the values.
+    values_.clear();
+    size_ = 0;
+
+    // Initialise all buckets to empty.
+    iterator end_it = values_.end();
+    for (size_t i = 0; i < num_buckets_; ++i)
+      buckets_[i].first = buckets_[i].last = end_it;
+  }
+
+private:
+  // Calculate the hash size for the specified number of elements.
+  static std::size_t hash_size(std::size_t num_elems)
+  {
+    static std::size_t sizes[] =
+    {
+#if defined(BOOST_ASIO_HASH_MAP_BUCKETS)
+      BOOST_ASIO_HASH_MAP_BUCKETS
+#else // BOOST_ASIO_HASH_MAP_BUCKETS
+      3, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
+      49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
+      12582917, 25165843
+#endif // BOOST_ASIO_HASH_MAP_BUCKETS
+    };
+    const std::size_t nth_size = sizeof(sizes) / sizeof(std::size_t) - 1;
+    for (std::size_t i = 0; i < nth_size; ++i)
+      if (num_elems < sizes[i])
+        return sizes[i];
+    return sizes[nth_size];
+  }
+
+  // Re-initialise the hash from the values already contained in the list.
+  void rehash(std::size_t num_buckets)
+  {
+    if (num_buckets == num_buckets_)
+      return;
+    BOOST_ASIO_ASSERT(num_buckets != 0);
+
+    iterator end_iter = values_.end();
+
+    // Update number of buckets and initialise all buckets to empty.
+    bucket_type* tmp = new bucket_type[num_buckets];
+    delete[] buckets_;
+    buckets_ = tmp;
+    num_buckets_ = num_buckets;
+    for (std::size_t i = 0; i < num_buckets_; ++i)
+      buckets_[i].first = buckets_[i].last = end_iter;
+
+    // Put all values back into the hash.
+    iterator iter = values_.begin();
+    while (iter != end_iter)
+    {
+      std::size_t bucket = calculate_hash_value(iter->first) % num_buckets_;
+      if (buckets_[bucket].last == end_iter)
+      {
+        buckets_[bucket].first = buckets_[bucket].last = iter++;
+      }
+      else if (++buckets_[bucket].last == iter)
+      {
+        ++iter;
+      }
+      else
+      {
+        values_.splice(buckets_[bucket].last, values_, iter++);
+        --buckets_[bucket].last;
+      }
+    }
+  }
+
+  // Insert an element into the values list by splicing from the spares list,
+  // if a spare is available, and otherwise by inserting a new element.
+  iterator values_insert(iterator it, const value_type& v)
+  {
+    if (spares_.empty())
+    {
+      return values_.insert(it, v);
+    }
+    else
+    {
+      spares_.front() = v;
+      values_.splice(it, spares_, spares_.begin());
+      return --it;
+    }
+  }
+
+  // Erase an element from the values list by splicing it to the spares list.
+  void values_erase(iterator it)
+  {
+    *it = value_type();
+    spares_.splice(spares_.begin(), values_, it);
+  }
+
+  // The number of elements in the hash.
+  std::size_t size_;
+
+  // The list of all values in the hash map.
+  std::list<value_type> values_;
+
+  // The list of spare nodes waiting to be recycled. Assumes that POD types only
+  // are stored in the hash map.
+  std::list<value_type> spares_;
+
+  // The type for a bucket in the hash table.
+  struct bucket_type
+  {
+    iterator first;
+    iterator last;
+  };
+
+  // The buckets in the hash.
+  bucket_type* buckets_;
+
+  // The number of buckets in the hash.
+  std::size_t num_buckets_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_HASH_MAP_HPP

+ 120 - 0
cpir-read/boost/boost/asio/detail/impl/buffer_sequence_adapter.ipp

@@ -0,0 +1,120 @@
+//
+// detail/impl/buffer_sequence_adapter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#include <robuffer.h>
+#include <windows.storage.streams.h>
+#include <wrl/implements.h>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class winrt_buffer_impl :
+  public Microsoft::WRL::RuntimeClass<
+    Microsoft::WRL::RuntimeClassFlags<
+      Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
+    ABI::Windows::Storage::Streams::IBuffer,
+    Windows::Storage::Streams::IBufferByteAccess>
+{
+public:
+  explicit winrt_buffer_impl(const boost::asio::const_buffer& b)
+  {
+    bytes_ = const_cast<byte*>(static_cast<const byte*>(b.data()));
+    length_ = b.size();
+    capacity_ = b.size();
+  }
+
+  explicit winrt_buffer_impl(const boost::asio::mutable_buffer& b)
+  {
+    bytes_ = static_cast<byte*>(b.data());
+    length_ = 0;
+    capacity_ = b.size();
+  }
+
+  ~winrt_buffer_impl()
+  {
+  }
+
+  STDMETHODIMP Buffer(byte** value)
+  {
+    *value = bytes_;
+    return S_OK;
+  }
+
+  STDMETHODIMP get_Capacity(UINT32* value)
+  {
+    *value = capacity_;
+    return S_OK;
+  }
+
+  STDMETHODIMP get_Length(UINT32 *value)
+  {
+    *value = length_;
+    return S_OK;
+  }
+
+  STDMETHODIMP put_Length(UINT32 value)
+  {
+    if (value > capacity_)
+      return E_INVALIDARG;
+    length_ = value;
+    return S_OK;
+  }
+
+private:
+  byte* bytes_;
+  UINT32 length_;
+  UINT32 capacity_;
+};
+
+void buffer_sequence_adapter_base::init_native_buffer(
+    buffer_sequence_adapter_base::native_buffer_type& buf,
+    const boost::asio::mutable_buffer& buffer)
+{
+  std::memset(&buf, 0, sizeof(native_buffer_type));
+  Microsoft::WRL::ComPtr<IInspectable> insp
+    = Microsoft::WRL::Make<winrt_buffer_impl>(buffer);
+  buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get());
+}
+
+void buffer_sequence_adapter_base::init_native_buffer(
+    buffer_sequence_adapter_base::native_buffer_type& buf,
+    const boost::asio::const_buffer& buffer)
+{
+  std::memset(&buf, 0, sizeof(native_buffer_type));
+  Microsoft::WRL::ComPtr<IInspectable> insp
+    = Microsoft::WRL::Make<winrt_buffer_impl>(buffer);
+  Platform::Object^ buf_obj = reinterpret_cast<Platform::Object^>(insp.Get());
+  buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get());
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP

+ 476 - 0
cpir-read/boost/boost/asio/detail/impl/descriptor_ops.ipp

@@ -0,0 +1,476 @@
+//
+// detail/impl/descriptor_ops.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP
+#define BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cerrno>
+#include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace descriptor_ops {
+
+int open(const char* path, int flags, boost::system::error_code& ec)
+{
+  errno = 0;
+  int result = error_wrapper(::open(path, flags), ec);
+  if (result >= 0)
+    ec = boost::system::error_code();
+  return result;
+}
+
+int close(int d, state_type& state, boost::system::error_code& ec)
+{
+  int result = 0;
+  if (d != -1)
+  {
+    errno = 0;
+    result = error_wrapper(::close(d), ec);
+
+    if (result != 0
+        && (ec == boost::asio::error::would_block
+          || ec == boost::asio::error::try_again))
+    {
+      // According to UNIX Network Programming Vol. 1, it is possible for
+      // close() to fail with EWOULDBLOCK under certain circumstances. What
+      // isn't clear is the state of the descriptor after this error. The one
+      // current OS where this behaviour is seen, Windows, says that the socket
+      // remains open. Therefore we'll put the descriptor back into blocking
+      // mode and have another attempt at closing it.
+#if defined(__SYMBIAN32__)
+      int flags = ::fcntl(d, F_GETFL, 0);
+      if (flags >= 0)
+        ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK);
+#else // defined(__SYMBIAN32__)
+      ioctl_arg_type arg = 0;
+      ::ioctl(d, FIONBIO, &arg);
+#endif // defined(__SYMBIAN32__)
+      state &= ~non_blocking;
+
+      errno = 0;
+      result = error_wrapper(::close(d), ec);
+    }
+  }
+
+  if (result == 0)
+    ec = boost::system::error_code();
+  return result;
+}
+
+bool set_user_non_blocking(int d, state_type& state,
+    bool value, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return false;
+  }
+
+  errno = 0;
+#if defined(__SYMBIAN32__)
+  int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
+  if (result >= 0)
+  {
+    errno = 0;
+    int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
+    result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
+  }
+#else // defined(__SYMBIAN32__)
+  ioctl_arg_type arg = (value ? 1 : 0);
+  int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
+#endif // defined(__SYMBIAN32__)
+
+  if (result >= 0)
+  {
+    ec = boost::system::error_code();
+    if (value)
+      state |= user_set_non_blocking;
+    else
+    {
+      // Clearing the user-set non-blocking mode always overrides any
+      // internally-set non-blocking flag. Any subsequent asynchronous
+      // operations will need to re-enable non-blocking I/O.
+      state &= ~(user_set_non_blocking | internal_non_blocking);
+    }
+    return true;
+  }
+
+  return false;
+}
+
+bool set_internal_non_blocking(int d, state_type& state,
+    bool value, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return false;
+  }
+
+  if (!value && (state & user_set_non_blocking))
+  {
+    // It does not make sense to clear the internal non-blocking flag if the
+    // user still wants non-blocking behaviour. Return an error and let the
+    // caller figure out whether to update the user-set non-blocking flag.
+    ec = boost::asio::error::invalid_argument;
+    return false;
+  }
+
+  errno = 0;
+#if defined(__SYMBIAN32__)
+  int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
+  if (result >= 0)
+  {
+    errno = 0;
+    int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
+    result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
+  }
+#else // defined(__SYMBIAN32__)
+  ioctl_arg_type arg = (value ? 1 : 0);
+  int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
+#endif // defined(__SYMBIAN32__)
+
+  if (result >= 0)
+  {
+    ec = boost::system::error_code();
+    if (value)
+      state |= internal_non_blocking;
+    else
+      state &= ~internal_non_blocking;
+    return true;
+  }
+
+  return false;
+}
+
+std::size_t sync_read(int d, state_type state, buf* bufs,
+    std::size_t count, bool all_empty, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return 0;
+  }
+
+  // A request to read 0 bytes on a stream is a no-op.
+  if (all_empty)
+  {
+    ec = boost::system::error_code();
+    return 0;
+  }
+
+  // Read some data.
+  for (;;)
+  {
+    // Try to complete the operation without blocking.
+    errno = 0;
+    signed_size_type bytes = error_wrapper(::readv(
+          d, bufs, static_cast<int>(count)), ec);
+
+    // Check if operation succeeded.
+    if (bytes > 0)
+      return bytes;
+
+    // Check for EOF.
+    if (bytes == 0)
+    {
+      ec = boost::asio::error::eof;
+      return 0;
+    }
+
+    // Operation failed.
+    if ((state & user_set_non_blocking)
+        || (ec != boost::asio::error::would_block
+          && ec != boost::asio::error::try_again))
+      return 0;
+
+    // Wait for descriptor to become ready.
+    if (descriptor_ops::poll_read(d, 0, ec) < 0)
+      return 0;
+  }
+}
+
+bool non_blocking_read(int d, buf* bufs, std::size_t count,
+    boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+  for (;;)
+  {
+    // Read some data.
+    errno = 0;
+    signed_size_type bytes = error_wrapper(::readv(
+          d, bufs, static_cast<int>(count)), ec);
+
+    // Check for end of stream.
+    if (bytes == 0)
+    {
+      ec = boost::asio::error::eof;
+      return true;
+    }
+
+    // Retry operation if interrupted by signal.
+    if (ec == boost::asio::error::interrupted)
+      continue;
+
+    // Check if we need to run the operation again.
+    if (ec == boost::asio::error::would_block
+        || ec == boost::asio::error::try_again)
+      return false;
+
+    // Operation is complete.
+    if (bytes > 0)
+    {
+      ec = boost::system::error_code();
+      bytes_transferred = bytes;
+    }
+    else
+      bytes_transferred = 0;
+
+    return true;
+  }
+}
+
+std::size_t sync_write(int d, state_type state, const buf* bufs,
+    std::size_t count, bool all_empty, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return 0;
+  }
+
+  // A request to write 0 bytes on a stream is a no-op.
+  if (all_empty)
+  {
+    ec = boost::system::error_code();
+    return 0;
+  }
+
+  // Write some data.
+  for (;;)
+  {
+    // Try to complete the operation without blocking.
+    errno = 0;
+    signed_size_type bytes = error_wrapper(::writev(
+          d, bufs, static_cast<int>(count)), ec);
+
+    // Check if operation succeeded.
+    if (bytes > 0)
+      return bytes;
+
+    // Operation failed.
+    if ((state & user_set_non_blocking)
+        || (ec != boost::asio::error::would_block
+          && ec != boost::asio::error::try_again))
+      return 0;
+
+    // Wait for descriptor to become ready.
+    if (descriptor_ops::poll_write(d, 0, ec) < 0)
+      return 0;
+  }
+}
+
+bool non_blocking_write(int d, const buf* bufs, std::size_t count,
+    boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+  for (;;)
+  {
+    // Write some data.
+    errno = 0;
+    signed_size_type bytes = error_wrapper(::writev(
+          d, bufs, static_cast<int>(count)), ec);
+
+    // Retry operation if interrupted by signal.
+    if (ec == boost::asio::error::interrupted)
+      continue;
+
+    // Check if we need to run the operation again.
+    if (ec == boost::asio::error::would_block
+        || ec == boost::asio::error::try_again)
+      return false;
+
+    // Operation is complete.
+    if (bytes >= 0)
+    {
+      ec = boost::system::error_code();
+      bytes_transferred = bytes;
+    }
+    else
+      bytes_transferred = 0;
+
+    return true;
+  }
+}
+
+int ioctl(int d, state_type& state, long cmd,
+    ioctl_arg_type* arg, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  errno = 0;
+  int result = error_wrapper(::ioctl(d, cmd, arg), ec);
+
+  if (result >= 0)
+  {
+    ec = boost::system::error_code();
+
+    // When updating the non-blocking mode we always perform the ioctl syscall,
+    // even if the flags would otherwise indicate that the descriptor is
+    // already in the correct state. This ensures that the underlying
+    // descriptor is put into the state that has been requested by the user. If
+    // the ioctl syscall was successful then we need to update the flags to
+    // match.
+    if (cmd == static_cast<long>(FIONBIO))
+    {
+      if (*arg)
+      {
+        state |= user_set_non_blocking;
+      }
+      else
+      {
+        // Clearing the non-blocking mode always overrides any internally-set
+        // non-blocking flag. Any subsequent asynchronous operations will need
+        // to re-enable non-blocking I/O.
+        state &= ~(user_set_non_blocking | internal_non_blocking);
+      }
+    }
+  }
+
+  return result;
+}
+
+int fcntl(int d, int cmd, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  errno = 0;
+  int result = error_wrapper(::fcntl(d, cmd), ec);
+  if (result != -1)
+    ec = boost::system::error_code();
+  return result;
+}
+
+int fcntl(int d, int cmd, long arg, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  errno = 0;
+  int result = error_wrapper(::fcntl(d, cmd, arg), ec);
+  if (result != -1)
+    ec = boost::system::error_code();
+  return result;
+}
+
+int poll_read(int d, state_type state, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  pollfd fds;
+  fds.fd = d;
+  fds.events = POLLIN;
+  fds.revents = 0;
+  int timeout = (state & user_set_non_blocking) ? 0 : -1;
+  errno = 0;
+  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  if (result == 0)
+    ec = (state & user_set_non_blocking)
+      ? boost::asio::error::would_block : boost::system::error_code();
+  else if (result > 0)
+    ec = boost::system::error_code();
+  return result;
+}
+
+int poll_write(int d, state_type state, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  pollfd fds;
+  fds.fd = d;
+  fds.events = POLLOUT;
+  fds.revents = 0;
+  int timeout = (state & user_set_non_blocking) ? 0 : -1;
+  errno = 0;
+  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  if (result == 0)
+    ec = (state & user_set_non_blocking)
+      ? boost::asio::error::would_block : boost::system::error_code();
+  else if (result > 0)
+    ec = boost::system::error_code();
+  return result;
+}
+
+int poll_error(int d, state_type state, boost::system::error_code& ec)
+{
+  if (d == -1)
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return -1;
+  }
+
+  pollfd fds;
+  fds.fd = d;
+  fds.events = POLLPRI | POLLERR | POLLHUP;
+  fds.revents = 0;
+  int timeout = (state & user_set_non_blocking) ? 0 : -1;
+  errno = 0;
+  int result = error_wrapper(::poll(&fds, 1, timeout), ec);
+  if (result == 0)
+    ec = (state & user_set_non_blocking)
+      ? boost::asio::error::would_block : boost::system::error_code();
+  else if (result > 0)
+    ec = boost::system::error_code();
+  return result;
+}
+
+} // namespace descriptor_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_WINDOWS)
+       //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+       //   && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP

+ 93 - 0
cpir-read/boost/boost/asio/detail/impl/dev_poll_reactor.hpp

@@ -0,0 +1,93 @@
+//
+// detail/impl/dev_poll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_add_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  if (shutdown_)
+  {
+    scheduler_.post_immediate_completion(op, false);
+    return;
+  }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  scheduler_.work_started();
+  if (earliest)
+    interrupter_.interrupt();
+}
+
+template <typename Time_Traits>
+std::size_t dev_poll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer,
+    std::size_t max_cancelled)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+  return n;
+}
+
+template <typename Time_Traits>
+void dev_poll_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& target,
+    typename timer_queue<Time_Traits>::per_timer_data& source)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(target, ops);
+  queue.move_timer(target, source);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP

+ 448 - 0
cpir-read/boost/boost/asio/detail/impl/dev_poll_reactor.ipp

@@ -0,0 +1,448 @@
+//
+// detail/impl/dev_poll_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#include <boost/asio/detail/dev_poll_reactor.hpp>
+#include <boost/asio/detail/assert.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+dev_poll_reactor::dev_poll_reactor(boost::asio::execution_context& ctx)
+  : boost::asio::detail::execution_context_service_base<dev_poll_reactor>(ctx),
+    scheduler_(use_service<scheduler>(ctx)),
+    mutex_(),
+    dev_poll_fd_(do_dev_poll_create()),
+    interrupter_(),
+    shutdown_(false)
+{
+  // Add the interrupter's descriptor to /dev/poll.
+  ::pollfd ev = { 0, 0, 0 };
+  ev.fd = interrupter_.read_descriptor();
+  ev.events = POLLIN | POLLERR;
+  ev.revents = 0;
+  ::write(dev_poll_fd_, &ev, sizeof(ev));
+}
+
+dev_poll_reactor::~dev_poll_reactor()
+{
+  shutdown();
+  ::close(dev_poll_fd_);
+}
+
+void dev_poll_reactor::shutdown()
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+  shutdown_ = true;
+  lock.unlock();
+
+  op_queue<operation> ops;
+
+  for (int i = 0; i < max_ops; ++i)
+    op_queue_[i].get_all_operations(ops);
+
+  timer_queues_.get_all_timers(ops);
+
+  scheduler_.abandon_operations(ops);
+} 
+
+void dev_poll_reactor::notify_fork(
+    boost::asio::execution_context::fork_event fork_ev)
+{
+  if (fork_ev == boost::asio::execution_context::fork_child)
+  {
+    detail::mutex::scoped_lock lock(mutex_);
+
+    if (dev_poll_fd_ != -1)
+      ::close(dev_poll_fd_);
+    dev_poll_fd_ = -1;
+    dev_poll_fd_ = do_dev_poll_create();
+
+    interrupter_.recreate();
+
+    // Add the interrupter's descriptor to /dev/poll.
+    ::pollfd ev = { 0, 0, 0 };
+    ev.fd = interrupter_.read_descriptor();
+    ev.events = POLLIN | POLLERR;
+    ev.revents = 0;
+    ::write(dev_poll_fd_, &ev, sizeof(ev));
+
+    // Re-register all descriptors with /dev/poll. The changes will be written
+    // to the /dev/poll descriptor the next time the reactor is run.
+    for (int i = 0; i < max_ops; ++i)
+    {
+      reactor_op_queue<socket_type>::iterator iter = op_queue_[i].begin();
+      reactor_op_queue<socket_type>::iterator end = op_queue_[i].end();
+      for (; iter != end; ++iter)
+      {
+        ::pollfd& pending_ev = add_pending_event_change(iter->first);
+        pending_ev.events |= POLLERR | POLLHUP;
+        switch (i)
+        {
+        case read_op: pending_ev.events |= POLLIN; break;
+        case write_op: pending_ev.events |= POLLOUT; break;
+        case except_op: pending_ev.events |= POLLPRI; break;
+        default: break;
+        }
+      }
+    }
+    interrupter_.interrupt();
+  }
+}
+
+void dev_poll_reactor::init_task()
+{
+  scheduler_.init_task();
+}
+
+int dev_poll_reactor::register_descriptor(socket_type, per_descriptor_data&)
+{
+  return 0;
+}
+
+int dev_poll_reactor::register_internal_descriptor(int op_type,
+    socket_type descriptor, per_descriptor_data&, reactor_op* op)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  op_queue_[op_type].enqueue_operation(descriptor, op);
+  ::pollfd& ev = add_pending_event_change(descriptor);
+  ev.events = POLLERR | POLLHUP;
+  switch (op_type)
+  {
+  case read_op: ev.events |= POLLIN; break;
+  case write_op: ev.events |= POLLOUT; break;
+  case except_op: ev.events |= POLLPRI; break;
+  default: break;
+  }
+  interrupter_.interrupt();
+
+  return 0;
+}
+
+void dev_poll_reactor::move_descriptor(socket_type,
+    dev_poll_reactor::per_descriptor_data&,
+    dev_poll_reactor::per_descriptor_data&)
+{
+}
+
+void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
+    dev_poll_reactor::per_descriptor_data&, reactor_op* op,
+    bool is_continuation, bool allow_speculative)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  if (shutdown_)
+  {
+    post_immediate_completion(op, is_continuation);
+    return;
+  }
+
+  if (allow_speculative)
+  {
+    if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor))
+    {
+      if (!op_queue_[op_type].has_operation(descriptor))
+      {
+        if (op->perform())
+        {
+          lock.unlock();
+          scheduler_.post_immediate_completion(op, is_continuation);
+          return;
+        }
+      }
+    }
+  }
+
+  bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+  scheduler_.work_started();
+  if (first)
+  {
+    ::pollfd& ev = add_pending_event_change(descriptor);
+    ev.events = POLLERR | POLLHUP;
+    if (op_type == read_op
+        || op_queue_[read_op].has_operation(descriptor))
+      ev.events |= POLLIN;
+    if (op_type == write_op
+        || op_queue_[write_op].has_operation(descriptor))
+      ev.events |= POLLOUT;
+    if (op_type == except_op
+        || op_queue_[except_op].has_operation(descriptor))
+      ev.events |= POLLPRI;
+    interrupter_.interrupt();
+  }
+}
+
+void dev_poll_reactor::cancel_ops(socket_type descriptor,
+    dev_poll_reactor::per_descriptor_data&)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+  cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void dev_poll_reactor::deregister_descriptor(socket_type descriptor,
+    dev_poll_reactor::per_descriptor_data&, bool)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  // Remove the descriptor from /dev/poll.
+  ::pollfd& ev = add_pending_event_change(descriptor);
+  ev.events = POLLREMOVE;
+  interrupter_.interrupt();
+
+  // Cancel any outstanding operations associated with the descriptor.
+  cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void dev_poll_reactor::deregister_internal_descriptor(
+    socket_type descriptor, dev_poll_reactor::per_descriptor_data&)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  // Remove the descriptor from /dev/poll. Since this function is only called
+  // during a fork, we can apply the change immediately.
+  ::pollfd ev = { 0, 0, 0 };
+  ev.fd = descriptor;
+  ev.events = POLLREMOVE;
+  ev.revents = 0;
+  ::write(dev_poll_fd_, &ev, sizeof(ev));
+
+  // Destroy all operations associated with the descriptor.
+  op_queue<operation> ops;
+  boost::system::error_code ec;
+  for (int i = 0; i < max_ops; ++i)
+    op_queue_[i].cancel_operations(descriptor, ops, ec);
+}
+
+void dev_poll_reactor::cleanup_descriptor_data(
+    dev_poll_reactor::per_descriptor_data&)
+{
+}
+
+void dev_poll_reactor::run(long usec, op_queue<operation>& ops)
+{
+  boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+  // We can return immediately if there's no work to do and the reactor is
+  // not supposed to block.
+  if (usec == 0 && op_queue_[read_op].empty() && op_queue_[write_op].empty()
+      && op_queue_[except_op].empty() && timer_queues_.all_empty())
+    return;
+
+  // Write the pending event registration changes to the /dev/poll descriptor.
+  std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size();
+  if (events_size > 0)
+  {
+    errno = 0;
+    int result = ::write(dev_poll_fd_,
+        &pending_event_changes_[0], events_size);
+    if (result != static_cast<int>(events_size))
+    {
+      boost::system::error_code ec = boost::system::error_code(
+          errno, boost::asio::error::get_system_category());
+      for (std::size_t i = 0; i < pending_event_changes_.size(); ++i)
+      {
+        int descriptor = pending_event_changes_[i].fd;
+        for (int j = 0; j < max_ops; ++j)
+          op_queue_[j].cancel_operations(descriptor, ops, ec);
+      }
+    }
+    pending_event_changes_.clear();
+    pending_event_change_index_.clear();
+  }
+
+  // Calculate timeout.
+  int timeout;
+  if (usec == 0)
+    timeout = 0;
+  else
+  {
+    timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1);
+    timeout = get_timeout(timeout);
+  }
+  lock.unlock();
+
+  // Block on the /dev/poll descriptor.
+  ::pollfd events[128] = { { 0, 0, 0 } };
+  ::dvpoll dp = { 0, 0, 0 };
+  dp.dp_fds = events;
+  dp.dp_nfds = 128;
+  dp.dp_timeout = timeout;
+  int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp);
+
+  lock.lock();
+
+  // Dispatch the waiting events.
+  for (int i = 0; i < num_events; ++i)
+  {
+    int descriptor = events[i].fd;
+    if (descriptor == interrupter_.read_descriptor())
+    {
+      interrupter_.reset();
+    }
+    else
+    {
+      bool more_reads = false;
+      bool more_writes = false;
+      bool more_except = false;
+
+      // Exception operations must be processed first to ensure that any
+      // out-of-band data is read before normal data.
+      if (events[i].events & (POLLPRI | POLLERR | POLLHUP))
+        more_except =
+          op_queue_[except_op].perform_operations(descriptor, ops);
+      else
+        more_except = op_queue_[except_op].has_operation(descriptor);
+
+      if (events[i].events & (POLLIN | POLLERR | POLLHUP))
+        more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
+      else
+        more_reads = op_queue_[read_op].has_operation(descriptor);
+
+      if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
+        more_writes = op_queue_[write_op].perform_operations(descriptor, ops);
+      else
+        more_writes = op_queue_[write_op].has_operation(descriptor);
+
+      if ((events[i].events & (POLLERR | POLLHUP)) != 0
+            && !more_except && !more_reads && !more_writes)
+      {
+        // If we have an event and no operations associated with the
+        // descriptor then we need to delete the descriptor from /dev/poll.
+        // The poll operation can produce POLLHUP or POLLERR events when there
+        // is no operation pending, so if we do not remove the descriptor we
+        // can end up in a tight polling loop.
+        ::pollfd ev = { 0, 0, 0 };
+        ev.fd = descriptor;
+        ev.events = POLLREMOVE;
+        ev.revents = 0;
+        ::write(dev_poll_fd_, &ev, sizeof(ev));
+      }
+      else
+      {
+        ::pollfd ev = { 0, 0, 0 };
+        ev.fd = descriptor;
+        ev.events = POLLERR | POLLHUP;
+        if (more_reads)
+          ev.events |= POLLIN;
+        if (more_writes)
+          ev.events |= POLLOUT;
+        if (more_except)
+          ev.events |= POLLPRI;
+        ev.revents = 0;
+        int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
+        if (result != sizeof(ev))
+        {
+          boost::system::error_code ec(errno,
+              boost::asio::error::get_system_category());
+          for (int j = 0; j < max_ops; ++j)
+            op_queue_[j].cancel_operations(descriptor, ops, ec);
+        }
+      }
+    }
+  }
+  timer_queues_.get_ready_timers(ops);
+}
+
+void dev_poll_reactor::interrupt()
+{
+  interrupter_.interrupt();
+}
+
+int dev_poll_reactor::do_dev_poll_create()
+{
+  int fd = ::open("/dev/poll", O_RDWR);
+  if (fd == -1)
+  {
+    boost::system::error_code ec(errno,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(ec, "/dev/poll");
+  }
+  return fd;
+}
+
+void dev_poll_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.insert(&queue);
+}
+
+void dev_poll_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.erase(&queue);
+}
+
+int dev_poll_reactor::get_timeout(int msec)
+{
+  // By default we will wait no longer than 5 minutes. This will ensure that
+  // any changes to the system clock are detected after no longer than this.
+  const int max_msec = 5 * 60 * 1000;
+  return timer_queues_.wait_duration_msec(
+      (msec < 0 || max_msec < msec) ? max_msec : msec);
+}
+
+void dev_poll_reactor::cancel_ops_unlocked(socket_type descriptor,
+    const boost::system::error_code& ec)
+{
+  bool need_interrupt = false;
+  op_queue<operation> ops;
+  for (int i = 0; i < max_ops; ++i)
+    need_interrupt = op_queue_[i].cancel_operations(
+        descriptor, ops, ec) || need_interrupt;
+  scheduler_.post_deferred_completions(ops);
+  if (need_interrupt)
+    interrupter_.interrupt();
+}
+
+::pollfd& dev_poll_reactor::add_pending_event_change(int descriptor)
+{
+  hash_map<int, std::size_t>::iterator iter
+    = pending_event_change_index_.find(descriptor);
+  if (iter == pending_event_change_index_.end())
+  {
+    std::size_t index = pending_event_changes_.size();
+    pending_event_changes_.reserve(pending_event_changes_.size() + 1);
+    pending_event_change_index_.insert(std::make_pair(descriptor, index));
+    pending_event_changes_.push_back(::pollfd());
+    pending_event_changes_[index].fd = descriptor;
+    pending_event_changes_[index].revents = 0;
+    return pending_event_changes_[index];
+  }
+  else
+  {
+    return pending_event_changes_[iter->second];
+  }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP

+ 91 - 0
cpir-read/boost/boost/asio/detail/impl/epoll_reactor.hpp

@@ -0,0 +1,91 @@
+//
+// detail/impl/epoll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_add_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
+{
+  mutex::scoped_lock lock(mutex_);
+
+  if (shutdown_)
+  {
+    scheduler_.post_immediate_completion(op, false);
+    return;
+  }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  scheduler_.work_started();
+  if (earliest)
+    update_timeout();
+}
+
+template <typename Time_Traits>
+std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer,
+    std::size_t max_cancelled)
+{
+  mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+  return n;
+}
+
+template <typename Time_Traits>
+void epoll_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& target,
+    typename timer_queue<Time_Traits>::per_timer_data& source)
+{
+  mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(target, ops);
+  queue.move_timer(target, source);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP

+ 789 - 0
cpir-read/boost/boost/asio/detail/impl/epoll_reactor.ipp

@@ -0,0 +1,789 @@
+//
+// detail/impl/epoll_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include <cstddef>
+#include <sys/epoll.h>
+#include <boost/asio/detail/epoll_reactor.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# include <sys/timerfd.h>
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+epoll_reactor::epoll_reactor(boost::asio::execution_context& ctx)
+  : execution_context_service_base<epoll_reactor>(ctx),
+    scheduler_(use_service<scheduler>(ctx)),
+    mutex_(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
+          REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
+    interrupter_(),
+    epoll_fd_(do_epoll_create()),
+    timer_fd_(do_timerfd_create()),
+    shutdown_(false),
+    registered_descriptors_mutex_(mutex_.enabled())
+{
+  // Add the interrupter's descriptor to epoll.
+  epoll_event ev = { 0, { 0 } };
+  ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+  ev.data.ptr = &interrupter_;
+  epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
+  interrupter_.interrupt();
+
+  // Add the timer descriptor to epoll.
+  if (timer_fd_ != -1)
+  {
+    ev.events = EPOLLIN | EPOLLERR;
+    ev.data.ptr = &timer_fd_;
+    epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
+  }
+}
+
+epoll_reactor::~epoll_reactor()
+{
+  if (epoll_fd_ != -1)
+    close(epoll_fd_);
+  if (timer_fd_ != -1)
+    close(timer_fd_);
+}
+
+void epoll_reactor::shutdown()
+{
+  mutex::scoped_lock lock(mutex_);
+  shutdown_ = true;
+  lock.unlock();
+
+  op_queue<operation> ops;
+
+  while (descriptor_state* state = registered_descriptors_.first())
+  {
+    for (int i = 0; i < max_ops; ++i)
+      ops.push(state->op_queue_[i]);
+    state->shutdown_ = true;
+    registered_descriptors_.free(state);
+  }
+
+  timer_queues_.get_all_timers(ops);
+
+  scheduler_.abandon_operations(ops);
+}
+
+void epoll_reactor::notify_fork(
+    boost::asio::execution_context::fork_event fork_ev)
+{
+  if (fork_ev == boost::asio::execution_context::fork_child)
+  {
+    if (epoll_fd_ != -1)
+      ::close(epoll_fd_);
+    epoll_fd_ = -1;
+    epoll_fd_ = do_epoll_create();
+
+    if (timer_fd_ != -1)
+      ::close(timer_fd_);
+    timer_fd_ = -1;
+    timer_fd_ = do_timerfd_create();
+
+    interrupter_.recreate();
+
+    // Add the interrupter's descriptor to epoll.
+    epoll_event ev = { 0, { 0 } };
+    ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+    ev.data.ptr = &interrupter_;
+    epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
+    interrupter_.interrupt();
+
+    // Add the timer descriptor to epoll.
+    if (timer_fd_ != -1)
+    {
+      ev.events = EPOLLIN | EPOLLERR;
+      ev.data.ptr = &timer_fd_;
+      epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
+    }
+
+    update_timeout();
+
+    // Re-register all descriptors with epoll.
+    mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+    for (descriptor_state* state = registered_descriptors_.first();
+        state != 0; state = state->next_)
+    {
+      ev.events = state->registered_events_;
+      ev.data.ptr = state;
+      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev);
+      if (result != 0)
+      {
+        boost::system::error_code ec(errno,
+            boost::asio::error::get_system_category());
+        boost::asio::detail::throw_error(ec, "epoll re-registration");
+      }
+    }
+  }
+}
+
+void epoll_reactor::init_task()
+{
+  scheduler_.init_task();
+}
+
+int epoll_reactor::register_descriptor(socket_type descriptor,
+    epoll_reactor::per_descriptor_data& descriptor_data)
+{
+  descriptor_data = allocate_descriptor_state();
+
+  BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
+        context(), static_cast<uintmax_t>(descriptor),
+        reinterpret_cast<uintmax_t>(descriptor_data)));
+
+  {
+    mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+    descriptor_data->reactor_ = this;
+    descriptor_data->descriptor_ = descriptor;
+    descriptor_data->shutdown_ = false;
+    for (int i = 0; i < max_ops; ++i)
+      descriptor_data->try_speculative_[i] = true;
+  }
+
+  epoll_event ev = { 0, { 0 } };
+  ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
+  descriptor_data->registered_events_ = ev.events;
+  ev.data.ptr = descriptor_data;
+  int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
+  if (result != 0)
+  {
+    if (errno == EPERM)
+    {
+      // This file descriptor type is not supported by epoll. However, if it is
+      // a regular file then operations on it will not block. We will allow
+      // this descriptor to be used and fail later if an operation on it would
+      // otherwise require a trip through the reactor.
+      descriptor_data->registered_events_ = 0;
+      return 0;
+    }
+    return errno;
+  }
+
+  return 0;
+}
+
+int epoll_reactor::register_internal_descriptor(
+    int op_type, socket_type descriptor,
+    epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op)
+{
+  descriptor_data = allocate_descriptor_state();
+
+  BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
+        context(), static_cast<uintmax_t>(descriptor),
+        reinterpret_cast<uintmax_t>(descriptor_data)));
+
+  {
+    mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+    descriptor_data->reactor_ = this;
+    descriptor_data->descriptor_ = descriptor;
+    descriptor_data->shutdown_ = false;
+    descriptor_data->op_queue_[op_type].push(op);
+    for (int i = 0; i < max_ops; ++i)
+      descriptor_data->try_speculative_[i] = true;
+  }
+
+  epoll_event ev = { 0, { 0 } };
+  ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET;
+  descriptor_data->registered_events_ = ev.events;
+  ev.data.ptr = descriptor_data;
+  int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
+  if (result != 0)
+    return errno;
+
+  return 0;
+}
+
+void epoll_reactor::move_descriptor(socket_type,
+    epoll_reactor::per_descriptor_data& target_descriptor_data,
+    epoll_reactor::per_descriptor_data& source_descriptor_data)
+{
+  target_descriptor_data = source_descriptor_data;
+  source_descriptor_data = 0;
+}
+
+void epoll_reactor::start_op(int op_type, socket_type descriptor,
+    epoll_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
+    bool is_continuation, bool allow_speculative)
+{
+  if (!descriptor_data)
+  {
+    op->ec_ = boost::asio::error::bad_descriptor;
+    post_immediate_completion(op, is_continuation);
+    return;
+  }
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (descriptor_data->shutdown_)
+  {
+    post_immediate_completion(op, is_continuation);
+    return;
+  }
+
+  if (descriptor_data->op_queue_[op_type].empty())
+  {
+    if (allow_speculative
+        && (op_type != read_op
+          || descriptor_data->op_queue_[except_op].empty()))
+    {
+      if (descriptor_data->try_speculative_[op_type])
+      {
+        if (reactor_op::status status = op->perform())
+        {
+          if (status == reactor_op::done_and_exhausted)
+            if (descriptor_data->registered_events_ != 0)
+              descriptor_data->try_speculative_[op_type] = false;
+          descriptor_lock.unlock();
+          scheduler_.post_immediate_completion(op, is_continuation);
+          return;
+        }
+      }
+
+      if (descriptor_data->registered_events_ == 0)
+      {
+        op->ec_ = boost::asio::error::operation_not_supported;
+        scheduler_.post_immediate_completion(op, is_continuation);
+        return;
+      }
+
+      if (op_type == write_op)
+      {
+        if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
+        {
+          epoll_event ev = { 0, { 0 } };
+          ev.events = descriptor_data->registered_events_ | EPOLLOUT;
+          ev.data.ptr = descriptor_data;
+          if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev) == 0)
+          {
+            descriptor_data->registered_events_ |= ev.events;
+          }
+          else
+          {
+            op->ec_ = boost::system::error_code(errno,
+                boost::asio::error::get_system_category());
+            scheduler_.post_immediate_completion(op, is_continuation);
+            return;
+          }
+        }
+      }
+    }
+    else if (descriptor_data->registered_events_ == 0)
+    {
+      op->ec_ = boost::asio::error::operation_not_supported;
+      scheduler_.post_immediate_completion(op, is_continuation);
+      return;
+    }
+    else
+    {
+      if (op_type == write_op)
+      {
+        descriptor_data->registered_events_ |= EPOLLOUT;
+      }
+
+      epoll_event ev = { 0, { 0 } };
+      ev.events = descriptor_data->registered_events_;
+      ev.data.ptr = descriptor_data;
+      epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
+    }
+  }
+
+  descriptor_data->op_queue_[op_type].push(op);
+  scheduler_.work_started();
+}
+
+void epoll_reactor::cancel_ops(socket_type,
+    epoll_reactor::per_descriptor_data& descriptor_data)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  op_queue<operation> ops;
+  for (int i = 0; i < max_ops; ++i)
+  {
+    while (reactor_op* op = descriptor_data->op_queue_[i].front())
+    {
+      op->ec_ = boost::asio::error::operation_aborted;
+      descriptor_data->op_queue_[i].pop();
+      ops.push(op);
+    }
+  }
+
+  descriptor_lock.unlock();
+
+  scheduler_.post_deferred_completions(ops);
+}
+
+void epoll_reactor::deregister_descriptor(socket_type descriptor,
+    epoll_reactor::per_descriptor_data& descriptor_data, bool closing)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (!descriptor_data->shutdown_)
+  {
+    if (closing)
+    {
+      // The descriptor will be automatically removed from the epoll set when
+      // it is closed.
+    }
+    else if (descriptor_data->registered_events_ != 0)
+    {
+      epoll_event ev = { 0, { 0 } };
+      epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
+    }
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+    {
+      while (reactor_op* op = descriptor_data->op_queue_[i].front())
+      {
+        op->ec_ = boost::asio::error::operation_aborted;
+        descriptor_data->op_queue_[i].pop();
+        ops.push(op);
+      }
+    }
+
+    descriptor_data->descriptor_ = -1;
+    descriptor_data->shutdown_ = true;
+
+    descriptor_lock.unlock();
+
+    BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
+          context(), static_cast<uintmax_t>(descriptor),
+          reinterpret_cast<uintmax_t>(descriptor_data)));
+
+    scheduler_.post_deferred_completions(ops);
+
+    // Leave descriptor_data set so that it will be freed by the subsequent
+    // call to cleanup_descriptor_data.
+  }
+  else
+  {
+    // We are shutting down, so prevent cleanup_descriptor_data from freeing
+    // the descriptor_data object and let the destructor free it instead.
+    descriptor_data = 0;
+  }
+}
+
+void epoll_reactor::deregister_internal_descriptor(socket_type descriptor,
+    epoll_reactor::per_descriptor_data& descriptor_data)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (!descriptor_data->shutdown_)
+  {
+    epoll_event ev = { 0, { 0 } };
+    epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      ops.push(descriptor_data->op_queue_[i]);
+
+    descriptor_data->descriptor_ = -1;
+    descriptor_data->shutdown_ = true;
+
+    descriptor_lock.unlock();
+
+    BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
+          context(), static_cast<uintmax_t>(descriptor),
+          reinterpret_cast<uintmax_t>(descriptor_data)));
+
+    // Leave descriptor_data set so that it will be freed by the subsequent
+    // call to cleanup_descriptor_data.
+  }
+  else
+  {
+    // We are shutting down, so prevent cleanup_descriptor_data from freeing
+    // the descriptor_data object and let the destructor free it instead.
+    descriptor_data = 0;
+  }
+}
+
+void epoll_reactor::cleanup_descriptor_data(
+    per_descriptor_data& descriptor_data)
+{
+  if (descriptor_data)
+  {
+    free_descriptor_state(descriptor_data);
+    descriptor_data = 0;
+  }
+}
+
+void epoll_reactor::run(long usec, op_queue<operation>& ops)
+{
+  // This code relies on the fact that the scheduler queues the reactor task
+  // behind all descriptor operations generated by this function. This means,
+  // that by the time we reach this point, any previously returned descriptor
+  // operations have already been dequeued. Therefore it is now safe for us to
+  // reuse and return them for the scheduler to queue again.
+
+  // Calculate timeout. Check the timer queues only if timerfd is not in use.
+  int timeout;
+  if (usec == 0)
+    timeout = 0;
+  else
+  {
+    timeout = (usec < 0) ? -1 : ((usec - 1) / 1000 + 1);
+    if (timer_fd_ == -1)
+    {
+      mutex::scoped_lock lock(mutex_);
+      timeout = get_timeout(timeout);
+    }
+  }
+
+  // Block on the epoll descriptor.
+  epoll_event events[128];
+  int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+  // Trace the waiting events.
+  for (int i = 0; i < num_events; ++i)
+  {
+    void* ptr = events[i].data.ptr;
+    if (ptr == &interrupter_)
+    {
+      // Ignore.
+    }
+# if defined(BOOST_ASIO_HAS_TIMERFD)
+    else if (ptr == &timer_fd_)
+    {
+      // Ignore.
+    }
+# endif // defined(BOOST_ASIO_HAS_TIMERFD)
+    else
+    {
+      unsigned event_mask = 0;
+      if ((events[i].events & EPOLLIN) != 0)
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_READ_EVENT;
+      if ((events[i].events & EPOLLOUT))
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT;
+      if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0)
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT;
+      BOOST_ASIO_HANDLER_REACTOR_EVENTS((context(),
+            reinterpret_cast<uintmax_t>(ptr), event_mask));
+    }
+  }
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+  bool check_timers = (timer_fd_ == -1);
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+  bool check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+  // Dispatch the waiting events.
+  for (int i = 0; i < num_events; ++i)
+  {
+    void* ptr = events[i].data.ptr;
+    if (ptr == &interrupter_)
+    {
+      // No need to reset the interrupter since we're leaving the descriptor
+      // in a ready-to-read state and relying on edge-triggered notifications
+      // to make it so that we only get woken up when the descriptor's epoll
+      // registration is updated.
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+      if (timer_fd_ == -1)
+        check_timers = true;
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+      check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+    }
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+    else if (ptr == &timer_fd_)
+    {
+      check_timers = true;
+    }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+    else
+    {
+      // The descriptor operation doesn't count as work in and of itself, so we
+      // don't call work_started() here. This still allows the scheduler to
+      // stop if the only remaining operations are descriptor operations.
+      descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
+      if (!ops.is_enqueued(descriptor_data))
+      {
+        descriptor_data->set_ready_events(events[i].events);
+        ops.push(descriptor_data);
+      }
+      else
+      {
+        descriptor_data->add_ready_events(events[i].events);
+      }
+    }
+  }
+
+  if (check_timers)
+  {
+    mutex::scoped_lock common_lock(mutex_);
+    timer_queues_.get_ready_timers(ops);
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+    if (timer_fd_ != -1)
+    {
+      itimerspec new_timeout;
+      itimerspec old_timeout;
+      int flags = get_timeout(new_timeout);
+      timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+    }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+  }
+}
+
+void epoll_reactor::interrupt()
+{
+  epoll_event ev = { 0, { 0 } };
+  ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+  ev.data.ptr = &interrupter_;
+  epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev);
+}
+
+int epoll_reactor::do_epoll_create()
+{
+#if defined(EPOLL_CLOEXEC)
+  int fd = epoll_create1(EPOLL_CLOEXEC);
+#else // defined(EPOLL_CLOEXEC)
+  int fd = -1;
+  errno = EINVAL;
+#endif // defined(EPOLL_CLOEXEC)
+
+  if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
+  {
+    fd = epoll_create(epoll_size);
+    if (fd != -1)
+      ::fcntl(fd, F_SETFD, FD_CLOEXEC);
+  }
+
+  if (fd == -1)
+  {
+    boost::system::error_code ec(errno,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(ec, "epoll");
+  }
+
+  return fd;
+}
+
+int epoll_reactor::do_timerfd_create()
+{
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# if defined(TFD_CLOEXEC)
+  int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
+# else // defined(TFD_CLOEXEC)
+  int fd = -1;
+  errno = EINVAL;
+# endif // defined(TFD_CLOEXEC)
+
+  if (fd == -1 && errno == EINVAL)
+  {
+    fd = timerfd_create(CLOCK_MONOTONIC, 0);
+    if (fd != -1)
+      ::fcntl(fd, F_SETFD, FD_CLOEXEC);
+  }
+
+  return fd;
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+  return -1;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+}
+
+epoll_reactor::descriptor_state* epoll_reactor::allocate_descriptor_state()
+{
+  mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+  return registered_descriptors_.alloc(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
+        REACTOR_IO, scheduler_.concurrency_hint()));
+}
+
+void epoll_reactor::free_descriptor_state(epoll_reactor::descriptor_state* s)
+{
+  mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+  registered_descriptors_.free(s);
+}
+
+void epoll_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.insert(&queue);
+}
+
+void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.erase(&queue);
+}
+
+void epoll_reactor::update_timeout()
+{
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+  if (timer_fd_ != -1)
+  {
+    itimerspec new_timeout;
+    itimerspec old_timeout;
+    int flags = get_timeout(new_timeout);
+    timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+    return;
+  }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+  interrupt();
+}
+
+int epoll_reactor::get_timeout(int msec)
+{
+  // By default we will wait no longer than 5 minutes. This will ensure that
+  // any changes to the system clock are detected after no longer than this.
+  const int max_msec = 5 * 60 * 1000;
+  return timer_queues_.wait_duration_msec(
+      (msec < 0 || max_msec < msec) ? max_msec : msec);
+}
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+int epoll_reactor::get_timeout(itimerspec& ts)
+{
+  ts.it_interval.tv_sec = 0;
+  ts.it_interval.tv_nsec = 0;
+
+  long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+  ts.it_value.tv_sec = usec / 1000000;
+  ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1;
+
+  return usec ? 0 : TFD_TIMER_ABSTIME;
+}
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+struct epoll_reactor::perform_io_cleanup_on_block_exit
+{
+  explicit perform_io_cleanup_on_block_exit(epoll_reactor* r)
+    : reactor_(r), first_op_(0)
+  {
+  }
+
+  ~perform_io_cleanup_on_block_exit()
+  {
+    if (first_op_)
+    {
+      // Post the remaining completed operations for invocation.
+      if (!ops_.empty())
+        reactor_->scheduler_.post_deferred_completions(ops_);
+
+      // A user-initiated operation has completed, but there's no need to
+      // explicitly call work_finished() here. Instead, we'll take advantage of
+      // the fact that the scheduler will call work_finished() once we return.
+    }
+    else
+    {
+      // No user-initiated operations have completed, so we need to compensate
+      // for the work_finished() call that the scheduler will make once this
+      // operation returns.
+      reactor_->scheduler_.compensating_work_started();
+    }
+  }
+
+  epoll_reactor* reactor_;
+  op_queue<operation> ops_;
+  operation* first_op_;
+};
+
+epoll_reactor::descriptor_state::descriptor_state(bool locking)
+  : operation(&epoll_reactor::descriptor_state::do_complete),
+    mutex_(locking)
+{
+}
+
+operation* epoll_reactor::descriptor_state::perform_io(uint32_t events)
+{
+  mutex_.lock();
+  perform_io_cleanup_on_block_exit io_cleanup(reactor_);
+  mutex::scoped_lock descriptor_lock(mutex_, mutex::scoped_lock::adopt_lock);
+
+  // Exception operations must be processed first to ensure that any
+  // out-of-band data is read before normal data.
+  static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
+  for (int j = max_ops - 1; j >= 0; --j)
+  {
+    if (events & (flag[j] | EPOLLERR | EPOLLHUP))
+    {
+      try_speculative_[j] = true;
+      while (reactor_op* op = op_queue_[j].front())
+      {
+        if (reactor_op::status status = op->perform())
+        {
+          op_queue_[j].pop();
+          io_cleanup.ops_.push(op);
+          if (status == reactor_op::done_and_exhausted)
+          {
+            try_speculative_[j] = false;
+            break;
+          }
+        }
+        else
+          break;
+      }
+    }
+  }
+
+  // The first operation will be returned for completion now. The others will
+  // be posted for later by the io_cleanup object's destructor.
+  io_cleanup.first_op_ = io_cleanup.ops_.front();
+  io_cleanup.ops_.pop();
+  return io_cleanup.first_op_;
+}
+
+void epoll_reactor::descriptor_state::do_complete(
+    void* owner, operation* base,
+    const boost::system::error_code& ec, std::size_t bytes_transferred)
+{
+  if (owner)
+  {
+    descriptor_state* descriptor_data = static_cast<descriptor_state*>(base);
+    uint32_t events = static_cast<uint32_t>(bytes_transferred);
+    if (operation* op = descriptor_data->perform_io(events))
+    {
+      op->complete(owner, ec, 0);
+    }
+  }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP

+ 167 - 0
cpir-read/boost/boost/asio/detail/impl/eventfd_select_interrupter.ipp

@@ -0,0 +1,167 @@
+//
+// detail/impl/eventfd_select_interrupter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EVENTFD)
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <asm/unistd.h>
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <sys/eventfd.h>
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+#include <boost/asio/detail/cstdint.hpp>
+#include <boost/asio/detail/eventfd_select_interrupter.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+eventfd_select_interrupter::eventfd_select_interrupter()
+{
+  open_descriptors();
+}
+
+void eventfd_select_interrupter::open_descriptors()
+{
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+  write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
+  if (read_descriptor_ != -1)
+  {
+    ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+    ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
+  }
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
+  write_descriptor_ = read_descriptor_ =
+    ::eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
+# else // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
+  errno = EINVAL;
+  write_descriptor_ = read_descriptor_ = -1;
+# endif // defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
+  if (read_descriptor_ == -1 && errno == EINVAL)
+  {
+    write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
+    if (read_descriptor_ != -1)
+    {
+      ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+      ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
+    }
+  }
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+
+  if (read_descriptor_ == -1)
+  {
+    int pipe_fds[2];
+    if (pipe(pipe_fds) == 0)
+    {
+      read_descriptor_ = pipe_fds[0];
+      ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+      ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
+      write_descriptor_ = pipe_fds[1];
+      ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+      ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC);
+    }
+    else
+    {
+      boost::system::error_code ec(errno,
+          boost::asio::error::get_system_category());
+      boost::asio::detail::throw_error(ec, "eventfd_select_interrupter");
+    }
+  }
+}
+
+eventfd_select_interrupter::~eventfd_select_interrupter()
+{
+  close_descriptors();
+}
+
+void eventfd_select_interrupter::close_descriptors()
+{
+  if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_)
+    ::close(write_descriptor_);
+  if (read_descriptor_ != -1)
+    ::close(read_descriptor_);
+}
+
+void eventfd_select_interrupter::recreate()
+{
+  close_descriptors();
+
+  write_descriptor_ = -1;
+  read_descriptor_ = -1;
+
+  open_descriptors();
+}
+
+void eventfd_select_interrupter::interrupt()
+{
+  uint64_t counter(1UL);
+  int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
+  (void)result;
+}
+
+bool eventfd_select_interrupter::reset()
+{
+  if (write_descriptor_ == read_descriptor_)
+  {
+    for (;;)
+    {
+      // Only perform one read. The kernel maintains an atomic counter.
+      uint64_t counter(0);
+      errno = 0;
+      int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
+      if (bytes_read < 0 && errno == EINTR)
+        continue;
+      bool was_interrupted = (bytes_read > 0);
+      return was_interrupted;
+    }
+  }
+  else
+  {
+    for (;;)
+    {
+      // Clear all data from the pipe.
+      char data[1024];
+      int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      if (bytes_read < 0 && errno == EINTR)
+        continue;
+      bool was_interrupted = (bytes_read > 0);
+      while (bytes_read == sizeof(data))
+        bytes_read = ::read(read_descriptor_, data, sizeof(data));
+      return was_interrupted;
+    }
+  }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EVENTFD)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP

+ 360 - 0
cpir-read/boost/boost/asio/detail/impl/handler_tracking.ipp

@@ -0,0 +1,360 @@
+//
+// detail/impl/handler_tracking.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP
+#define BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_CUSTOM_HANDLER_TRACKING)
+
+// The handler tracking implementation is provided by the user-specified header.
+
+#elif defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+#include <cstdarg>
+#include <cstdio>
+#include <boost/asio/detail/handler_tracking.hpp>
+
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+# include <boost/asio/time_traits.hpp>
+#elif defined(BOOST_ASIO_HAS_CHRONO)
+# include <boost/asio/detail/chrono.hpp>
+# include <boost/asio/detail/chrono_time_traits.hpp>
+# include <boost/asio/wait_traits.hpp>
+#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/socket_types.hpp>
+#elif !defined(BOOST_ASIO_WINDOWS)
+# include <unistd.h>
+#endif // !defined(BOOST_ASIO_WINDOWS)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+struct handler_tracking_timestamp
+{
+  uint64_t seconds;
+  uint64_t microseconds;
+
+  handler_tracking_timestamp()
+  {
+#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
+    boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
+    boost::posix_time::time_duration now =
+      boost::posix_time::microsec_clock::universal_time() - epoch;
+#elif defined(BOOST_ASIO_HAS_CHRONO)
+    typedef chrono_time_traits<chrono::system_clock,
+        boost::asio::wait_traits<chrono::system_clock> > traits_helper;
+    traits_helper::posix_time_duration now(
+        chrono::system_clock::now().time_since_epoch());
+#endif
+    seconds = static_cast<uint64_t>(now.total_seconds());
+    microseconds = static_cast<uint64_t>(now.total_microseconds() % 1000000);
+  }
+};
+
+struct handler_tracking::tracking_state
+{
+  static_mutex mutex_;
+  uint64_t next_id_;
+  tss_ptr<completion>* current_completion_;
+};
+
+handler_tracking::tracking_state* handler_tracking::get_state()
+{
+  static tracking_state state = { BOOST_ASIO_STATIC_MUTEX_INIT, 1, 0 };
+  return &state;
+}
+
+void handler_tracking::init()
+{
+  static tracking_state* state = get_state();
+
+  state->mutex_.init();
+
+  static_mutex::scoped_lock lock(state->mutex_);
+  if (state->current_completion_ == 0)
+    state->current_completion_ = new tss_ptr<completion>;
+}
+
+void handler_tracking::creation(execution_context&,
+    handler_tracking::tracked_handler& h,
+    const char* object_type, void* object,
+    uintmax_t /*native_handle*/, const char* op_name)
+{
+  static tracking_state* state = get_state();
+
+  static_mutex::scoped_lock lock(state->mutex_);
+  h.id_ = state->next_id_++;
+  lock.unlock();
+
+  handler_tracking_timestamp timestamp;
+
+  uint64_t current_id = 0;
+  if (completion* current_completion = *state->current_completion_)
+    current_id = current_completion->id_;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|%I64u*%I64u|%.20s@%p.%.50s\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|%llu*%llu|%.20s@%p.%.50s\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      current_id, h.id_, object_type, object, op_name);
+}
+
+handler_tracking::completion::completion(
+    const handler_tracking::tracked_handler& h)
+  : id_(h.id_),
+    invoked_(false),
+    next_(*get_state()->current_completion_)
+{
+  *get_state()->current_completion_ = this;
+}
+
+handler_tracking::completion::~completion()
+{
+  if (id_)
+  {
+    handler_tracking_timestamp timestamp;
+
+    write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+        "@asio|%I64u.%06I64u|%c%I64u|\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+        "@asio|%llu.%06llu|%c%llu|\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+        timestamp.seconds, timestamp.microseconds,
+        invoked_ ? '!' : '~', id_);
+  }
+
+  *get_state()->current_completion_ = next_;
+}
+
+void handler_tracking::completion::invocation_begin()
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|>%I64u|\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|>%llu|\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds, id_);
+
+  invoked_ = true;
+}
+
+void handler_tracking::completion::invocation_begin(
+    const boost::system::error_code& ec)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|>%llu|ec=%.20s:%d\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      id_, ec.category().name(), ec.value());
+
+  invoked_ = true;
+}
+
+void handler_tracking::completion::invocation_begin(
+    const boost::system::error_code& ec, std::size_t bytes_transferred)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,bytes_transferred=%I64u\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,bytes_transferred=%llu\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      id_, ec.category().name(), ec.value(),
+      static_cast<uint64_t>(bytes_transferred));
+
+  invoked_ = true;
+}
+
+void handler_tracking::completion::invocation_begin(
+    const boost::system::error_code& ec, int signal_number)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,signal_number=%d\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,signal_number=%d\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      id_, ec.category().name(), ec.value(), signal_number);
+
+  invoked_ = true;
+}
+
+void handler_tracking::completion::invocation_begin(
+    const boost::system::error_code& ec, const char* arg)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|>%I64u|ec=%.20s:%d,%.50s\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|>%llu|ec=%.20s:%d,%.50s\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      id_, ec.category().name(), ec.value(), arg);
+
+  invoked_ = true;
+}
+
+void handler_tracking::completion::invocation_end()
+{
+  if (id_)
+  {
+    handler_tracking_timestamp timestamp;
+
+    write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+        "@asio|%I64u.%06I64u|<%I64u|\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+        "@asio|%llu.%06llu|<%llu|\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+        timestamp.seconds, timestamp.microseconds, id_);
+
+    id_ = 0;
+  }
+}
+
+void handler_tracking::operation(execution_context&,
+    const char* object_type, void* object,
+    uintmax_t /*native_handle*/, const char* op_name)
+{
+  static tracking_state* state = get_state();
+
+  handler_tracking_timestamp timestamp;
+
+  unsigned long long current_id = 0;
+  if (completion* current_completion = *state->current_completion_)
+    current_id = current_completion->id_;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|%I64u|%.20s@%p.%.50s\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|%llu|%.20s@%p.%.50s\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      current_id, object_type, object, op_name);
+}
+
+void handler_tracking::reactor_registration(execution_context& /*context*/,
+    uintmax_t /*native_handle*/, uintmax_t /*registration*/)
+{
+}
+
+void handler_tracking::reactor_deregistration(execution_context& /*context*/,
+    uintmax_t /*native_handle*/, uintmax_t /*registration*/)
+{
+}
+
+void handler_tracking::reactor_events(execution_context& /*context*/,
+    uintmax_t /*native_handle*/, unsigned /*events*/)
+{
+}
+
+void handler_tracking::reactor_operation(
+    const tracked_handler& h, const char* op_name,
+    const boost::system::error_code& ec)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      h.id_, op_name, ec.category().name(), ec.value());
+}
+
+void handler_tracking::reactor_operation(
+    const tracked_handler& h, const char* op_name,
+    const boost::system::error_code& ec, std::size_t bytes_transferred)
+{
+  handler_tracking_timestamp timestamp;
+
+  write_line(
+#if defined(BOOST_ASIO_WINDOWS)
+      "@asio|%I64u.%06I64u|.%I64u|%s,ec=%.20s:%d,bytes_transferred=%I64u\n",
+#else // defined(BOOST_ASIO_WINDOWS)
+      "@asio|%llu.%06llu|.%llu|%s,ec=%.20s:%d,bytes_transferred=%llu\n",
+#endif // defined(BOOST_ASIO_WINDOWS)
+      timestamp.seconds, timestamp.microseconds,
+      h.id_, op_name, ec.category().name(), ec.value(),
+      static_cast<uint64_t>(bytes_transferred));
+}
+
+void handler_tracking::write_line(const char* format, ...)
+{
+  using namespace std; // For sprintf (or equivalent).
+
+  va_list args;
+  va_start(args, format);
+
+  char line[256] = "";
+#if defined(BOOST_ASIO_HAS_SECURE_RTL)
+  int length = vsprintf_s(line, sizeof(line), format, args);
+#else // defined(BOOST_ASIO_HAS_SECURE_RTL)
+  int length = vsprintf(line, format, args);
+#endif // defined(BOOST_ASIO_HAS_SECURE_RTL)
+
+  va_end(args);
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  wchar_t wline[256] = L"";
+  mbstowcs_s(0, wline, sizeof(wline) / sizeof(wchar_t), line, length);
+  ::OutputDebugStringW(wline);
+#elif defined(BOOST_ASIO_WINDOWS)
+  HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE);
+  DWORD bytes_written = 0;
+  ::WriteFile(stderr_handle, line, length, &bytes_written, 0);
+#else // defined(BOOST_ASIO_WINDOWS)
+  ::write(STDERR_FILENO, line, length);
+#endif // defined(BOOST_ASIO_WINDOWS)
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_HANDLER_TRACKING_IPP

+ 95 - 0
cpir-read/boost/boost/asio/detail/impl/kqueue_reactor.hpp

@@ -0,0 +1,95 @@
+//
+// detail/impl/kqueue_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_KQUEUE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_add_timer_queue(queue);
+}
+
+// Remove a timer queue from the reactor.
+template <typename Time_Traits>
+void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+  do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op)
+{
+  mutex::scoped_lock lock(mutex_);
+
+  if (shutdown_)
+  {
+    scheduler_.post_immediate_completion(op, false);
+    return;
+  }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  scheduler_.work_started();
+  if (earliest)
+    interrupt();
+}
+
+template <typename Time_Traits>
+std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer,
+    std::size_t max_cancelled)
+{
+  mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+  return n;
+}
+
+template <typename Time_Traits>
+void kqueue_reactor::move_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& target,
+    typename timer_queue<Time_Traits>::per_timer_data& source)
+{
+  mutex::scoped_lock lock(mutex_);
+  op_queue<operation> ops;
+  queue.cancel_timer(target, ops);
+  queue.move_timer(target, source);
+  lock.unlock();
+  scheduler_.post_deferred_completions(ops);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP

+ 568 - 0
cpir-read/boost/boost/asio/detail/impl/kqueue_reactor.ipp

@@ -0,0 +1,568 @@
+//
+// detail/impl/kqueue_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_KQUEUE)
+
+#include <boost/asio/detail/kqueue_reactor.hpp>
+#include <boost/asio/detail/scheduler.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+#if defined(__NetBSD__)
+# define BOOST_ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \
+    EV_SET(ev, ident, filt, flags, fflags, data, \
+      reinterpret_cast<intptr_t>(static_cast<void*>(udata)))
+#else
+# define BOOST_ASIO_KQUEUE_EV_SET(ev, ident, filt, flags, fflags, data, udata) \
+    EV_SET(ev, ident, filt, flags, fflags, data, udata)
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+kqueue_reactor::kqueue_reactor(boost::asio::execution_context& ctx)
+  : execution_context_service_base<kqueue_reactor>(ctx),
+    scheduler_(use_service<scheduler>(ctx)),
+    mutex_(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
+          REACTOR_REGISTRATION, scheduler_.concurrency_hint())),
+    kqueue_fd_(do_kqueue_create()),
+    interrupter_(),
+    shutdown_(false),
+    registered_descriptors_mutex_(mutex_.enabled())
+{
+  struct kevent events[1];
+  BOOST_ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),
+      EVFILT_READ, EV_ADD, 0, 0, &interrupter_);
+  if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1)
+  {
+    boost::system::error_code error(errno,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(error);
+  }
+}
+
+kqueue_reactor::~kqueue_reactor()
+{
+  close(kqueue_fd_);
+}
+
+void kqueue_reactor::shutdown()
+{
+  mutex::scoped_lock lock(mutex_);
+  shutdown_ = true;
+  lock.unlock();
+
+  op_queue<operation> ops;
+
+  while (descriptor_state* state = registered_descriptors_.first())
+  {
+    for (int i = 0; i < max_ops; ++i)
+      ops.push(state->op_queue_[i]);
+    state->shutdown_ = true;
+    registered_descriptors_.free(state);
+  }
+
+  timer_queues_.get_all_timers(ops);
+
+  scheduler_.abandon_operations(ops);
+}
+
+void kqueue_reactor::notify_fork(
+    boost::asio::execution_context::fork_event fork_ev)
+{
+  if (fork_ev == boost::asio::execution_context::fork_child)
+  {
+    // The kqueue descriptor is automatically closed in the child.
+    kqueue_fd_ = -1;
+    kqueue_fd_ = do_kqueue_create();
+
+    interrupter_.recreate();
+
+    struct kevent events[2];
+    BOOST_ASIO_KQUEUE_EV_SET(&events[0], interrupter_.read_descriptor(),
+        EVFILT_READ, EV_ADD, 0, 0, &interrupter_);
+    if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1)
+    {
+      boost::system::error_code ec(errno,
+          boost::asio::error::get_system_category());
+      boost::asio::detail::throw_error(ec, "kqueue interrupter registration");
+    }
+
+    // Re-register all descriptors with kqueue.
+    mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+    for (descriptor_state* state = registered_descriptors_.first();
+        state != 0; state = state->next_)
+    {
+      if (state->num_kevents_ > 0)
+      {
+        BOOST_ASIO_KQUEUE_EV_SET(&events[0], state->descriptor_,
+            EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, state);
+        BOOST_ASIO_KQUEUE_EV_SET(&events[1], state->descriptor_,
+            EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, state);
+        if (::kevent(kqueue_fd_, events, state->num_kevents_, 0, 0, 0) == -1)
+        {
+          boost::system::error_code ec(errno,
+              boost::asio::error::get_system_category());
+          boost::asio::detail::throw_error(ec, "kqueue re-registration");
+        }
+      }
+    }
+  }
+}
+
+void kqueue_reactor::init_task()
+{
+  scheduler_.init_task();
+}
+
+int kqueue_reactor::register_descriptor(socket_type descriptor,
+    kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+  descriptor_data = allocate_descriptor_state();
+
+  BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
+        context(), static_cast<uintmax_t>(descriptor),
+        reinterpret_cast<uintmax_t>(descriptor_data)));
+
+  mutex::scoped_lock lock(descriptor_data->mutex_);
+
+  descriptor_data->descriptor_ = descriptor;
+  descriptor_data->num_kevents_ = 0;
+  descriptor_data->shutdown_ = false;
+
+  return 0;
+}
+
+int kqueue_reactor::register_internal_descriptor(
+    int op_type, socket_type descriptor,
+    kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op)
+{
+  descriptor_data = allocate_descriptor_state();
+
+  BOOST_ASIO_HANDLER_REACTOR_REGISTRATION((
+        context(), static_cast<uintmax_t>(descriptor),
+        reinterpret_cast<uintmax_t>(descriptor_data)));
+
+  mutex::scoped_lock lock(descriptor_data->mutex_);
+
+  descriptor_data->descriptor_ = descriptor;
+  descriptor_data->num_kevents_ = 1;
+  descriptor_data->shutdown_ = false;
+  descriptor_data->op_queue_[op_type].push(op);
+
+  struct kevent events[1];
+  BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ,
+      EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+  if (::kevent(kqueue_fd_, events, 1, 0, 0, 0) == -1)
+    return errno;
+
+  return 0;
+}
+
+void kqueue_reactor::move_descriptor(socket_type,
+    kqueue_reactor::per_descriptor_data& target_descriptor_data,
+    kqueue_reactor::per_descriptor_data& source_descriptor_data)
+{
+  target_descriptor_data = source_descriptor_data;
+  source_descriptor_data = 0;
+}
+
+void kqueue_reactor::start_op(int op_type, socket_type descriptor,
+    kqueue_reactor::per_descriptor_data& descriptor_data, reactor_op* op,
+    bool is_continuation, bool allow_speculative)
+{
+  if (!descriptor_data)
+  {
+    op->ec_ = boost::asio::error::bad_descriptor;
+    post_immediate_completion(op, is_continuation);
+    return;
+  }
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (descriptor_data->shutdown_)
+  {
+    post_immediate_completion(op, is_continuation);
+    return;
+  }
+
+  if (descriptor_data->op_queue_[op_type].empty())
+  {
+    static const int num_kevents[max_ops] = { 1, 2, 1 };
+
+    if (allow_speculative
+        && (op_type != read_op
+          || descriptor_data->op_queue_[except_op].empty()))
+    {
+      if (op->perform())
+      {
+        descriptor_lock.unlock();
+        scheduler_.post_immediate_completion(op, is_continuation);
+        return;
+      }
+
+      if (descriptor_data->num_kevents_ < num_kevents[op_type])
+      {
+        struct kevent events[2];
+        BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ,
+            EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+        BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE,
+            EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+        if (::kevent(kqueue_fd_, events, num_kevents[op_type], 0, 0, 0) != -1)
+        {
+          descriptor_data->num_kevents_ = num_kevents[op_type];
+        }
+        else
+        {
+          op->ec_ = boost::system::error_code(errno,
+              boost::asio::error::get_system_category());
+          scheduler_.post_immediate_completion(op, is_continuation);
+          return;
+        }
+      }
+    }
+    else
+    {
+      if (descriptor_data->num_kevents_ < num_kevents[op_type])
+        descriptor_data->num_kevents_ = num_kevents[op_type];
+
+      struct kevent events[2];
+      BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor, EVFILT_READ,
+          EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+      BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor, EVFILT_WRITE,
+          EV_ADD | EV_CLEAR, 0, 0, descriptor_data);
+      ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0);
+    }
+  }
+
+  descriptor_data->op_queue_[op_type].push(op);
+  scheduler_.work_started();
+}
+
+void kqueue_reactor::cancel_ops(socket_type,
+    kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  op_queue<operation> ops;
+  for (int i = 0; i < max_ops; ++i)
+  {
+    while (reactor_op* op = descriptor_data->op_queue_[i].front())
+    {
+      op->ec_ = boost::asio::error::operation_aborted;
+      descriptor_data->op_queue_[i].pop();
+      ops.push(op);
+    }
+  }
+
+  descriptor_lock.unlock();
+
+  scheduler_.post_deferred_completions(ops);
+}
+
+void kqueue_reactor::deregister_descriptor(socket_type descriptor,
+    kqueue_reactor::per_descriptor_data& descriptor_data, bool closing)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (!descriptor_data->shutdown_)
+  {
+    if (closing)
+    {
+      // The descriptor will be automatically removed from the kqueue when it
+      // is closed.
+    }
+    else
+    {
+      struct kevent events[2];
+      BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor,
+          EVFILT_READ, EV_DELETE, 0, 0, 0);
+      BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor,
+          EVFILT_WRITE, EV_DELETE, 0, 0, 0);
+      ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0);
+    }
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+    {
+      while (reactor_op* op = descriptor_data->op_queue_[i].front())
+      {
+        op->ec_ = boost::asio::error::operation_aborted;
+        descriptor_data->op_queue_[i].pop();
+        ops.push(op);
+      }
+    }
+
+    descriptor_data->descriptor_ = -1;
+    descriptor_data->shutdown_ = true;
+
+    descriptor_lock.unlock();
+
+    BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
+          context(), static_cast<uintmax_t>(descriptor),
+          reinterpret_cast<uintmax_t>(descriptor_data)));
+
+    scheduler_.post_deferred_completions(ops);
+
+    // Leave descriptor_data set so that it will be freed by the subsequent
+    // call to cleanup_descriptor_data.
+  }
+  else
+  {
+    // We are shutting down, so prevent cleanup_descriptor_data from freeing
+    // the descriptor_data object and let the destructor free it instead.
+    descriptor_data = 0;
+  }
+}
+
+void kqueue_reactor::deregister_internal_descriptor(socket_type descriptor,
+    kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+  if (!descriptor_data)
+    return;
+
+  mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+  if (!descriptor_data->shutdown_)
+  {
+    struct kevent events[2];
+    BOOST_ASIO_KQUEUE_EV_SET(&events[0], descriptor,
+        EVFILT_READ, EV_DELETE, 0, 0, 0);
+    BOOST_ASIO_KQUEUE_EV_SET(&events[1], descriptor,
+        EVFILT_WRITE, EV_DELETE, 0, 0, 0);
+    ::kevent(kqueue_fd_, events, descriptor_data->num_kevents_, 0, 0, 0);
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      ops.push(descriptor_data->op_queue_[i]);
+
+    descriptor_data->descriptor_ = -1;
+    descriptor_data->shutdown_ = true;
+
+    descriptor_lock.unlock();
+
+    BOOST_ASIO_HANDLER_REACTOR_DEREGISTRATION((
+          context(), static_cast<uintmax_t>(descriptor),
+          reinterpret_cast<uintmax_t>(descriptor_data)));
+
+    // Leave descriptor_data set so that it will be freed by the subsequent
+    // call to cleanup_descriptor_data.
+  }
+  else
+  {
+    // We are shutting down, so prevent cleanup_descriptor_data from freeing
+    // the descriptor_data object and let the destructor free it instead.
+    descriptor_data = 0;
+  }
+}
+
+void kqueue_reactor::cleanup_descriptor_data(
+    per_descriptor_data& descriptor_data)
+{
+  if (descriptor_data)
+  {
+    free_descriptor_state(descriptor_data);
+    descriptor_data = 0;
+  }
+}
+
+void kqueue_reactor::run(long usec, op_queue<operation>& ops)
+{
+  mutex::scoped_lock lock(mutex_);
+
+  // Determine how long to block while waiting for events.
+  timespec timeout_buf = { 0, 0 };
+  timespec* timeout = usec ? get_timeout(usec, timeout_buf) : &timeout_buf;
+
+  lock.unlock();
+
+  // Block on the kqueue descriptor.
+  struct kevent events[128];
+  int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout);
+
+#if defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+  // Trace the waiting events.
+  for (int i = 0; i < num_events; ++i)
+  {
+    void* ptr = reinterpret_cast<void*>(events[i].udata);
+    if (ptr != &interrupter_)
+    {
+      unsigned event_mask = 0;
+      switch (events[i].filter)
+      {
+      case EVFILT_READ:
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_READ_EVENT;
+        break;
+      case EVFILT_WRITE:
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_WRITE_EVENT;
+        break;
+      }
+      if ((events[i].flags & (EV_ERROR | EV_OOBAND)) != 0)
+        event_mask |= BOOST_ASIO_HANDLER_REACTOR_ERROR_EVENT;
+      BOOST_ASIO_HANDLER_REACTOR_EVENTS((context(),
+            reinterpret_cast<uintmax_t>(ptr), event_mask));
+    }
+  }
+#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TRACKING)
+
+  // Dispatch the waiting events.
+  for (int i = 0; i < num_events; ++i)
+  {
+    void* ptr = reinterpret_cast<void*>(events[i].udata);
+    if (ptr == &interrupter_)
+    {
+      interrupter_.reset();
+    }
+    else
+    {
+      descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
+      mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+      if (events[i].filter == EVFILT_WRITE
+          && descriptor_data->num_kevents_ == 2
+          && descriptor_data->op_queue_[write_op].empty())
+      {
+        // Some descriptor types, like serial ports, don't seem to support
+        // EV_CLEAR with EVFILT_WRITE. Since we have no pending write
+        // operations we'll remove the EVFILT_WRITE registration here so that
+        // we don't end up in a tight spin.
+        struct kevent delete_events[1];
+        BOOST_ASIO_KQUEUE_EV_SET(&delete_events[0],
+            descriptor_data->descriptor_, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
+        ::kevent(kqueue_fd_, delete_events, 1, 0, 0, 0);
+        descriptor_data->num_kevents_ = 1;
+      }
+
+      // Exception operations must be processed first to ensure that any
+      // out-of-band data is read before normal data.
+#if defined(__NetBSD__)
+      static const unsigned int filter[max_ops] =
+#else
+      static const int filter[max_ops] =
+#endif
+        { EVFILT_READ, EVFILT_WRITE, EVFILT_READ };
+      for (int j = max_ops - 1; j >= 0; --j)
+      {
+        if (events[i].filter == filter[j])
+        {
+          if (j != except_op || events[i].flags & EV_OOBAND)
+          {
+            while (reactor_op* op = descriptor_data->op_queue_[j].front())
+            {
+              if (events[i].flags & EV_ERROR)
+              {
+                op->ec_ = boost::system::error_code(
+                    static_cast<int>(events[i].data),
+                    boost::asio::error::get_system_category());
+                descriptor_data->op_queue_[j].pop();
+                ops.push(op);
+              }
+              if (op->perform())
+              {
+                descriptor_data->op_queue_[j].pop();
+                ops.push(op);
+              }
+              else
+                break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  lock.lock();
+  timer_queues_.get_ready_timers(ops);
+}
+
+void kqueue_reactor::interrupt()
+{
+  interrupter_.interrupt();
+}
+
+int kqueue_reactor::do_kqueue_create()
+{
+  int fd = ::kqueue();
+  if (fd == -1)
+  {
+    boost::system::error_code ec(errno,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(ec, "kqueue");
+  }
+  return fd;
+}
+
+kqueue_reactor::descriptor_state* kqueue_reactor::allocate_descriptor_state()
+{
+  mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+  return registered_descriptors_.alloc(BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
+        REACTOR_IO, scheduler_.concurrency_hint()));
+}
+
+void kqueue_reactor::free_descriptor_state(kqueue_reactor::descriptor_state* s)
+{
+  mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+  registered_descriptors_.free(s);
+}
+
+void kqueue_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.insert(&queue);
+}
+
+void kqueue_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+  mutex::scoped_lock lock(mutex_);
+  timer_queues_.erase(&queue);
+}
+
+timespec* kqueue_reactor::get_timeout(long usec, timespec& ts)
+{
+  // By default we will wait no longer than 5 minutes. This will ensure that
+  // any changes to the system clock are detected after no longer than this.
+  const long max_usec = 5 * 60 * 1000 * 1000;
+  usec = timer_queues_.wait_duration_usec(
+      (usec < 0 || max_usec < usec) ? max_usec : usec);
+  ts.tv_sec = usec / 1000000;
+  ts.tv_nsec = (usec % 1000000) * 1000;
+  return &ts;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#undef BOOST_ASIO_KQUEUE_EV_SET
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP

+ 76 - 0
cpir-read/boost/boost/asio/detail/impl/null_event.ipp

@@ -0,0 +1,76 @@
+//
+// detail/impl/null_event.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_NULL_EVENT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_NULL_EVENT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <thread>
+#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+# include <boost/asio/detail/socket_types.hpp>
+#else
+# include <unistd.h>
+# if defined(__hpux)
+#  include <sys/time.h>
+# endif
+# if !defined(__hpux) || defined(__SELECT)
+#  include <sys/select.h>
+# endif
+#endif
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+void null_event::do_wait()
+{
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  std::this_thread::sleep_until((std::chrono::steady_clock::time_point::max)());
+#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+  ::Sleep(INFINITE);
+#else
+  ::pause();
+#endif
+}
+
+void null_event::do_wait_for_usec(long usec)
+{
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+  std::this_thread::sleep_for(std::chrono::microseconds(usec));
+#elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
+  ::Sleep(usec / 1000);
+#elif defined(__hpux) && defined(__SELECT)
+  timespec ts;
+  ts.tv_sec = usec / 1000000;
+  ts.tv_nsec = (usec % 1000000) * 1000;
+  ::pselect(0, 0, 0, 0, &ts, 0);
+#else
+  timeval tv;
+  tv.tv_sec = usec / 1000000;
+  tv.tv_usec = usec % 1000000;
+  ::select(0, 0, 0, 0, &tv);
+#endif
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_NULL_EVENT_IPP

+ 126 - 0
cpir-read/boost/boost/asio/detail/impl/pipe_select_interrupter.ipp

@@ -0,0 +1,126 @@
+//
+// detail/impl/pipe_select_interrupter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+#if !defined(BOOST_ASIO_WINDOWS)
+#if !defined(__CYGWIN__)
+#if !defined(__SYMBIAN32__)
+#if !defined(BOOST_ASIO_HAS_EVENTFD)
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <boost/asio/detail/pipe_select_interrupter.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+pipe_select_interrupter::pipe_select_interrupter()
+{
+  open_descriptors();
+}
+
+void pipe_select_interrupter::open_descriptors()
+{
+  int pipe_fds[2];
+  if (pipe(pipe_fds) == 0)
+  {
+    read_descriptor_ = pipe_fds[0];
+    ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+    write_descriptor_ = pipe_fds[1];
+    ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+
+#if defined(FD_CLOEXEC)
+    ::fcntl(read_descriptor_, F_SETFD, FD_CLOEXEC);
+    ::fcntl(write_descriptor_, F_SETFD, FD_CLOEXEC);
+#endif // defined(FD_CLOEXEC)
+  }
+  else
+  {
+    boost::system::error_code ec(errno,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(ec, "pipe_select_interrupter");
+  }
+}
+
+pipe_select_interrupter::~pipe_select_interrupter()
+{
+  close_descriptors();
+}
+
+void pipe_select_interrupter::close_descriptors()
+{
+  if (read_descriptor_ != -1)
+    ::close(read_descriptor_);
+  if (write_descriptor_ != -1)
+    ::close(write_descriptor_);
+}
+
+void pipe_select_interrupter::recreate()
+{
+  close_descriptors();
+
+  write_descriptor_ = -1;
+  read_descriptor_ = -1;
+
+  open_descriptors();
+}
+
+void pipe_select_interrupter::interrupt()
+{
+  char byte = 0;
+  signed_size_type result = ::write(write_descriptor_, &byte, 1);
+  (void)result;
+}
+
+bool pipe_select_interrupter::reset()
+{
+  for (;;)
+  {
+    char data[1024];
+    signed_size_type bytes_read = ::read(read_descriptor_, data, sizeof(data));
+    if (bytes_read < 0 && errno == EINTR)
+      continue;
+    bool was_interrupted = (bytes_read > 0);
+    while (bytes_read == sizeof(data))
+      bytes_read = ::read(read_descriptor_, data, sizeof(data));
+    return was_interrupted;
+  }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_EVENTFD)
+#endif // !defined(__SYMBIAN32__)
+#endif // !defined(__CYGWIN__)
+#endif // !defined(BOOST_ASIO_WINDOWS)
+#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP

+ 61 - 0
cpir-read/boost/boost/asio/detail/impl/posix_event.ipp

@@ -0,0 +1,61 @@
+//
+// detail/impl/posix_event.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_PTHREADS)
+
+#include <boost/asio/detail/posix_event.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_event::posix_event()
+  : state_(0)
+{
+#if (defined(__MACH__) && defined(__APPLE__)) \
+      || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
+  int error = ::pthread_cond_init(&cond_, 0);
+#else // (defined(__MACH__) && defined(__APPLE__))
+      // || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
+  ::pthread_condattr_t attr;
+  ::pthread_condattr_init(&attr);
+  int error = ::pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+  if (error == 0)
+    error = ::pthread_cond_init(&cond_, &attr);
+#endif // (defined(__MACH__) && defined(__APPLE__))
+       // || (defined(__ANDROID__) && (__ANDROID_API__ < 21))
+
+  boost::system::error_code ec(error,
+      boost::asio::error::get_system_category());
+  boost::asio::detail::throw_error(ec, "event");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_PTHREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP

+ 48 - 0
cpir-read/boost/boost/asio/detail/impl/posix_mutex.ipp

@@ -0,0 +1,48 @@
+//
+// detail/impl/posix_mutex.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_PTHREADS)
+
+#include <boost/asio/detail/posix_mutex.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_mutex::posix_mutex()
+{
+  int error = ::pthread_mutex_init(&mutex_, 0);
+  boost::system::error_code ec(error,
+      boost::asio::error::get_system_category());
+  boost::asio::detail::throw_error(ec, "mutex");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_PTHREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP

+ 86 - 0
cpir-read/boost/boost/asio/detail/impl/posix_thread.ipp

@@ -0,0 +1,86 @@
+//
+// detail/impl/posix_thread.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_PTHREADS)
+
+#include <boost/asio/detail/posix_thread.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_thread::~posix_thread()
+{
+  if (!joined_)
+    ::pthread_detach(thread_);
+}
+
+void posix_thread::join()
+{
+  if (!joined_)
+  {
+    ::pthread_join(thread_, 0);
+    joined_ = true;
+  }
+}
+
+std::size_t posix_thread::hardware_concurrency()
+{
+#if defined(_SC_NPROCESSORS_ONLN)
+  long result = sysconf(_SC_NPROCESSORS_ONLN);
+  if (result > 0)
+    return result;
+#endif // defined(_SC_NPROCESSORS_ONLN)
+  return 0;
+}
+
+void posix_thread::start_thread(func_base* arg)
+{
+  int error = ::pthread_create(&thread_, 0,
+        boost_asio_detail_posix_thread_function, arg);
+  if (error != 0)
+  {
+    delete arg;
+    boost::system::error_code ec(error,
+        boost::asio::error::get_system_category());
+    boost::asio::detail::throw_error(ec, "thread");
+  }
+}
+
+void* boost_asio_detail_posix_thread_function(void* arg)
+{
+  posix_thread::auto_func_base_ptr func = {
+      static_cast<posix_thread::func_base*>(arg) };
+  func.ptr->run();
+  return 0;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_PTHREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP

+ 48 - 0
cpir-read/boost/boost/asio/detail/impl/posix_tss_ptr.ipp

@@ -0,0 +1,48 @@
+//
+// detail/impl/posix_tss_ptr.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_PTHREADS)
+
+#include <boost/asio/detail/posix_tss_ptr.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+void posix_tss_ptr_create(pthread_key_t& key)
+{
+  int error = ::pthread_key_create(&key, 0);
+  boost::system::error_code ec(error,
+      boost::asio::error::get_system_category());
+  boost::asio::detail::throw_error(ec, "tss");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_PTHREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP

+ 224 - 0
cpir-read/boost/boost/asio/detail/impl/reactive_descriptor_service.ipp

@@ -0,0 +1,224 @@
+//
+// detail/impl/reactive_descriptor_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_WINDOWS) \
+  && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
+  && !defined(__CYGWIN__)
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/detail/reactive_descriptor_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_descriptor_service::reactive_descriptor_service(
+    boost::asio::io_context& io_context)
+  : service_base<reactive_descriptor_service>(io_context),
+    reactor_(boost::asio::use_service<reactor>(io_context))
+{
+  reactor_.init_task();
+}
+
+void reactive_descriptor_service::shutdown()
+{
+}
+
+void reactive_descriptor_service::construct(
+    reactive_descriptor_service::implementation_type& impl)
+{
+  impl.descriptor_ = -1;
+  impl.state_ = 0;
+}
+
+void reactive_descriptor_service::move_construct(
+    reactive_descriptor_service::implementation_type& impl,
+    reactive_descriptor_service::implementation_type& other_impl)
+{
+  impl.descriptor_ = other_impl.descriptor_;
+  other_impl.descriptor_ = -1;
+
+  impl.state_ = other_impl.state_;
+  other_impl.state_ = 0;
+
+  reactor_.move_descriptor(impl.descriptor_,
+      impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_descriptor_service::move_assign(
+    reactive_descriptor_service::implementation_type& impl,
+    reactive_descriptor_service& other_service,
+    reactive_descriptor_service::implementation_type& other_impl)
+{
+  destroy(impl);
+
+  impl.descriptor_ = other_impl.descriptor_;
+  other_impl.descriptor_ = -1;
+
+  impl.state_ = other_impl.state_;
+  other_impl.state_ = 0;
+
+  other_service.reactor_.move_descriptor(impl.descriptor_,
+      impl.reactor_data_, other_impl.reactor_data_);
+}
+
+void reactive_descriptor_service::destroy(
+    reactive_descriptor_service::implementation_type& impl)
+{
+  if (is_open(impl))
+  {
+    BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+          "descriptor", &impl, impl.descriptor_, "close"));
+
+    reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
+        (impl.state_ & descriptor_ops::possible_dup) == 0);
+
+    boost::system::error_code ignored_ec;
+    descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
+
+    reactor_.cleanup_descriptor_data(impl.reactor_data_);
+  }
+}
+
+boost::system::error_code reactive_descriptor_service::assign(
+    reactive_descriptor_service::implementation_type& impl,
+    const native_handle_type& native_descriptor, boost::system::error_code& ec)
+{
+  if (is_open(impl))
+  {
+    ec = boost::asio::error::already_open;
+    return ec;
+  }
+
+  if (int err = reactor_.register_descriptor(
+        native_descriptor, impl.reactor_data_))
+  {
+    ec = boost::system::error_code(err,
+        boost::asio::error::get_system_category());
+    return ec;
+  }
+
+  impl.descriptor_ = native_descriptor;
+  impl.state_ = descriptor_ops::possible_dup;
+  ec = boost::system::error_code();
+  return ec;
+}
+
+boost::system::error_code reactive_descriptor_service::close(
+    reactive_descriptor_service::implementation_type& impl,
+    boost::system::error_code& ec)
+{
+  if (is_open(impl))
+  {
+    BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+          "descriptor", &impl, impl.descriptor_, "close"));
+
+    reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_,
+        (impl.state_ & descriptor_ops::possible_dup) == 0);
+
+    descriptor_ops::close(impl.descriptor_, impl.state_, ec);
+
+    reactor_.cleanup_descriptor_data(impl.reactor_data_);
+  }
+  else
+  {
+    ec = boost::system::error_code();
+  }
+
+  // The descriptor is closed by the OS even if close() returns an error.
+  //
+  // (Actually, POSIX says the state of the descriptor is unspecified. On
+  // Linux the descriptor is apparently closed anyway; e.g. see
+  //   http://lkml.org/lkml/2005/9/10/129
+  // We'll just have to assume that other OSes follow the same behaviour.)
+  construct(impl);
+
+  return ec;
+}
+
+reactive_descriptor_service::native_handle_type
+reactive_descriptor_service::release(
+    reactive_descriptor_service::implementation_type& impl)
+{
+  native_handle_type descriptor = impl.descriptor_;
+
+  if (is_open(impl))
+  {
+    BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+          "descriptor", &impl, impl.descriptor_, "release"));
+
+    reactor_.deregister_descriptor(impl.descriptor_, impl.reactor_data_, false);
+    reactor_.cleanup_descriptor_data(impl.reactor_data_);
+    construct(impl);
+  }
+
+  return descriptor;
+}
+
+boost::system::error_code reactive_descriptor_service::cancel(
+    reactive_descriptor_service::implementation_type& impl,
+    boost::system::error_code& ec)
+{
+  if (!is_open(impl))
+  {
+    ec = boost::asio::error::bad_descriptor;
+    return ec;
+  }
+
+  BOOST_ASIO_HANDLER_OPERATION((reactor_.context(),
+        "descriptor", &impl, impl.descriptor_, "cancel"));
+
+  reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_);
+  ec = boost::system::error_code();
+  return ec;
+}
+
+void reactive_descriptor_service::start_op(
+    reactive_descriptor_service::implementation_type& impl,
+    int op_type, reactor_op* op, bool is_continuation,
+    bool is_non_blocking, bool noop)
+{
+  if (!noop)
+  {
+    if ((impl.state_ & descriptor_ops::non_blocking) ||
+        descriptor_ops::set_internal_non_blocking(
+          impl.descriptor_, impl.state_, true, op->ec_))
+    {
+      reactor_.start_op(op_type, impl.descriptor_,
+          impl.reactor_data_, op, is_continuation, is_non_blocking);
+      return;
+    }
+  }
+
+  reactor_.post_immediate_completion(op, is_continuation);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_WINDOWS)
+       //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
+       //   && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP

Неке датотеке нису приказане због велике количине промена