passenger 6.0.14 → 6.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (964) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +51 -1
  3. data/CONTRIBUTORS +2 -0
  4. data/build/common_library.rb +1 -0
  5. data/src/agent/Core/Config.h +1 -1
  6. data/src/agent/Core/Controller/Config.h +1 -1
  7. data/src/agent/SpawnEnvSetupper/SpawnEnvSetupperMain.cpp +24 -2
  8. data/src/agent/Watchdog/Config.h +1 -1
  9. data/src/agent/Watchdog/WatchdogMain.cpp +4 -0
  10. data/src/cxx_supportlib/BackgroundEventLoop.cpp +4 -0
  11. data/src/cxx_supportlib/Constants.h +1 -1
  12. data/src/cxx_supportlib/LoggingKit/Context.h +1 -1
  13. data/src/cxx_supportlib/SafeLibev.h +2 -0
  14. data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/detail/find_iterator.hpp +11 -3
  15. data/src/cxx_supportlib/vendor-modified/boost/algorithm/string/find_iterator.hpp +27 -1
  16. data/src/cxx_supportlib/vendor-modified/boost/align/detail/aligned_alloc_sunos.hpp +34 -0
  17. data/src/cxx_supportlib/vendor-modified/boost/asio/any_io_executor.hpp +42 -39
  18. data/src/cxx_supportlib/vendor-modified/boost/asio/append.hpp +80 -0
  19. data/src/cxx_supportlib/vendor-modified/boost/asio/as_tuple.hpp +141 -0
  20. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_allocator.hpp +4 -4
  21. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_cancellation_slot.hpp +4 -3
  22. data/src/cxx_supportlib/vendor-modified/boost/asio/associated_executor.hpp +4 -4
  23. data/src/cxx_supportlib/vendor-modified/boost/asio/associator.hpp +1 -1
  24. data/src/cxx_supportlib/vendor-modified/boost/asio/async_result.hpp +363 -1
  25. data/src/cxx_supportlib/vendor-modified/boost/asio/awaitable.hpp +10 -1
  26. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_datagram_socket.hpp +208 -115
  27. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_deadline_timer.hpp +28 -16
  28. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_file.hpp +831 -0
  29. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_io_object.hpp +1 -1
  30. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_random_access_file.hpp +703 -0
  31. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_raw_socket.hpp +210 -117
  32. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_readable_pipe.hpp +637 -0
  33. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_seq_packet_socket.hpp +84 -47
  34. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_serial_port.hpp +123 -30
  35. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_signal_set.hpp +36 -14
  36. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket.hpp +58 -26
  37. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_acceptor.hpp +303 -150
  38. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_iostream.hpp +1 -1
  39. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_socket_streambuf.hpp +1 -1
  40. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_stream_file.hpp +756 -0
  41. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_stream_socket.hpp +153 -84
  42. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_streambuf.hpp +1 -1
  43. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_streambuf_fwd.hpp +1 -1
  44. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_waitable_timer.hpp +28 -16
  45. data/src/cxx_supportlib/vendor-modified/boost/asio/basic_writable_pipe.hpp +633 -0
  46. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_allocator.hpp +724 -0
  47. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_cancellation_slot.hpp +11 -8
  48. data/src/cxx_supportlib/vendor-modified/boost/asio/bind_executor.hpp +36 -20
  49. data/src/cxx_supportlib/vendor-modified/boost/asio/buffer.hpp +222 -42
  50. data/src/cxx_supportlib/vendor-modified/boost/asio/buffer_registration.hpp +330 -0
  51. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_read_stream.hpp +38 -6
  52. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_read_stream_fwd.hpp +1 -1
  53. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_stream.hpp +34 -5
  54. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_stream_fwd.hpp +1 -1
  55. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_write_stream.hpp +38 -6
  56. data/src/cxx_supportlib/vendor-modified/boost/asio/buffered_write_stream_fwd.hpp +1 -1
  57. data/src/cxx_supportlib/vendor-modified/boost/asio/buffers_iterator.hpp +1 -1
  58. data/src/cxx_supportlib/vendor-modified/boost/asio/cancellation_signal.hpp +10 -64
  59. data/src/cxx_supportlib/vendor-modified/boost/asio/cancellation_state.hpp +1 -1
  60. data/src/cxx_supportlib/vendor-modified/boost/asio/cancellation_type.hpp +1 -1
  61. data/src/cxx_supportlib/vendor-modified/boost/asio/co_spawn.hpp +33 -9
  62. data/src/cxx_supportlib/vendor-modified/boost/asio/completion_condition.hpp +1 -1
  63. data/src/cxx_supportlib/vendor-modified/boost/asio/compose.hpp +682 -12
  64. data/src/cxx_supportlib/vendor-modified/boost/asio/connect.hpp +132 -61
  65. data/src/cxx_supportlib/vendor-modified/boost/asio/connect_pipe.hpp +85 -0
  66. data/src/cxx_supportlib/vendor-modified/boost/asio/coroutine.hpp +1 -1
  67. data/src/cxx_supportlib/vendor-modified/boost/asio/deadline_timer.hpp +1 -1
  68. data/src/cxx_supportlib/vendor-modified/boost/asio/defer.hpp +128 -42
  69. data/src/cxx_supportlib/vendor-modified/boost/asio/deferred.hpp +677 -0
  70. data/src/cxx_supportlib/vendor-modified/boost/asio/detached.hpp +6 -5
  71. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/array.hpp +1 -1
  72. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/array_fwd.hpp +1 -1
  73. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/assert.hpp +1 -1
  74. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/atomic_count.hpp +4 -1
  75. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/base_from_cancellation_state.hpp +1 -1
  76. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/base_from_completion_cond.hpp +1 -1
  77. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/bind_handler.hpp +1 -1
  78. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/blocking_executor_op.hpp +1 -1
  79. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffer_resize_guard.hpp +1 -1
  80. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffer_sequence_adapter.hpp +192 -1
  81. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/buffered_stream_storage.hpp +1 -1
  82. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/bulk_executor_op.hpp +1 -1
  83. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/call_stack.hpp +1 -1
  84. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/chrono.hpp +1 -1
  85. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/chrono_time_traits.hpp +1 -1
  86. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/completion_handler.hpp +1 -1
  87. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/concurrency_hint.hpp +1 -1
  88. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/conditionally_enabled_event.hpp +1 -1
  89. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/conditionally_enabled_mutex.hpp +1 -1
  90. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/config.hpp +233 -10
  91. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/consuming_buffers.hpp +38 -1
  92. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/cstddef.hpp +1 -1
  93. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/cstdint.hpp +3 -1
  94. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/date_time_fwd.hpp +1 -1
  95. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/deadline_timer_service.hpp +1 -1
  96. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/dependent_type.hpp +1 -1
  97. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_ops.hpp +42 -2
  98. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_read_op.hpp +3 -1
  99. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/descriptor_write_op.hpp +3 -1
  100. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/dev_poll_reactor.hpp +10 -2
  101. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/epoll_reactor.hpp +4 -2
  102. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/event.hpp +1 -1
  103. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/eventfd_select_interrupter.hpp +1 -1
  104. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/exception.hpp +42 -0
  105. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/executor_function.hpp +1 -1
  106. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/executor_op.hpp +1 -1
  107. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/fd_set_adapter.hpp +1 -1
  108. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/fenced_block.hpp +1 -1
  109. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/functional.hpp +1 -1
  110. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/future.hpp +1 -1
  111. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_arm_fenced_block.hpp +1 -1
  112. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_hppa_fenced_block.hpp +1 -1
  113. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_sync_fenced_block.hpp +1 -1
  114. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/gcc_x86_fenced_block.hpp +2 -2
  115. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/global.hpp +1 -1
  116. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_alloc_helpers.hpp +1 -1
  117. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_cont_helpers.hpp +1 -1
  118. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_invoke_helpers.hpp +1 -1
  119. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_tracking.hpp +1 -1
  120. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_type_requirements.hpp +1 -1
  121. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/handler_work.hpp +1 -1
  122. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/hash_map.hpp +1 -1
  123. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/buffer_sequence_adapter.ipp +1 -1
  124. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/descriptor_ops.ipp +330 -5
  125. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/dev_poll_reactor.hpp +13 -1
  126. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/dev_poll_reactor.ipp +1 -1
  127. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/epoll_reactor.hpp +1 -1
  128. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/epoll_reactor.ipp +1 -1
  129. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/eventfd_select_interrupter.ipp +1 -1
  130. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/handler_tracking.ipp +1 -1
  131. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/io_uring_descriptor_service.ipp +207 -0
  132. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/io_uring_file_service.ipp +142 -0
  133. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/io_uring_service.hpp +114 -0
  134. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/io_uring_service.ipp +882 -0
  135. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/io_uring_socket_service_base.ipp +251 -0
  136. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/kqueue_reactor.hpp +1 -1
  137. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/kqueue_reactor.ipp +1 -1
  138. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/null_event.ipp +1 -1
  139. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/pipe_select_interrupter.ipp +1 -1
  140. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_event.ipp +1 -1
  141. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_mutex.ipp +1 -1
  142. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/{reactive_serial_port_service.ipp → posix_serial_port_service.ipp} +38 -19
  143. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_thread.ipp +1 -1
  144. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/posix_tss_ptr.ipp +1 -1
  145. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/reactive_descriptor_service.ipp +9 -2
  146. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/reactive_socket_service_base.ipp +6 -4
  147. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/resolver_service_base.ipp +1 -1
  148. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/scheduler.ipp +19 -4
  149. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/select_reactor.hpp +1 -1
  150. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/select_reactor.ipp +36 -1
  151. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/service_registry.hpp +1 -1
  152. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/service_registry.ipp +1 -1
  153. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/signal_set_service.ipp +108 -3
  154. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/socket_ops.ipp +126 -121
  155. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/socket_select_interrupter.ipp +4 -4
  156. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_executor_service.hpp +1 -1
  157. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_executor_service.ipp +1 -1
  158. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_service.hpp +1 -1
  159. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/strand_service.ipp +1 -1
  160. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/thread_context.ipp +1 -1
  161. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/throw_error.ipp +10 -6
  162. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/timer_queue_ptime.ipp +1 -1
  163. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/impl/timer_queue_set.ipp +1 -1
  164. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_control.hpp +1 -1
  165. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_object_impl.hpp +11 -2
  166. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_descriptor_read_at_op.hpp +194 -0
  167. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_descriptor_read_op.hpp +189 -0
  168. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_descriptor_service.hpp +681 -0
  169. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_descriptor_write_at_op.hpp +188 -0
  170. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_descriptor_write_op.hpp +184 -0
  171. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_file_service.hpp +264 -0
  172. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_null_buffers_op.hpp +115 -0
  173. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_operation.hpp +86 -0
  174. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_service.hpp +320 -0
  175. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_accept_op.hpp +283 -0
  176. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_connect_op.hpp +141 -0
  177. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_recv_op.hpp +204 -0
  178. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_recvfrom_op.hpp +205 -0
  179. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_recvmsg_op.hpp +191 -0
  180. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_send_op.hpp +190 -0
  181. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_sendto_op.hpp +193 -0
  182. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_service.hpp +633 -0
  183. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_socket_service_base.hpp +665 -0
  184. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/io_uring_wait_op.hpp +113 -0
  185. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/is_buffer_sequence.hpp +27 -1
  186. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/is_executor.hpp +1 -1
  187. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/keyword_tss_ptr.hpp +1 -1
  188. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/kqueue_reactor.hpp +4 -2
  189. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/local_free_on_block_exit.hpp +1 -1
  190. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/macos_fenced_block.hpp +1 -1
  191. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/memory.hpp +17 -1
  192. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/mutex.hpp +1 -1
  193. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/non_const_lvalue.hpp +1 -1
  194. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/noncopyable.hpp +1 -1
  195. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_event.hpp +1 -1
  196. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_fenced_block.hpp +1 -1
  197. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_global.hpp +1 -1
  198. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_mutex.hpp +1 -5
  199. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_reactor.hpp +19 -4
  200. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_signal_blocker.hpp +1 -1
  201. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_socket_service.hpp +1 -1
  202. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_static_mutex.hpp +1 -1
  203. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_thread.hpp +1 -1
  204. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/null_tss_ptr.hpp +1 -1
  205. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/object_pool.hpp +1 -1
  206. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/old_win_sdk_compat.hpp +1 -1
  207. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/op_queue.hpp +1 -1
  208. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/operation.hpp +1 -1
  209. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/pipe_select_interrupter.hpp +1 -1
  210. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/pop_options.hpp +9 -1
  211. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_event.hpp +1 -1
  212. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_fd_set_adapter.hpp +1 -1
  213. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_global.hpp +1 -1
  214. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_mutex.hpp +1 -1
  215. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/{reactive_serial_port_service.hpp → posix_serial_port_service.hpp} +30 -18
  216. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_signal_blocker.hpp +1 -1
  217. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_static_mutex.hpp +1 -1
  218. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_thread.hpp +1 -1
  219. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/posix_tss_ptr.hpp +1 -1
  220. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/push_options.hpp +12 -2
  221. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_descriptor_service.hpp +29 -8
  222. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_null_buffers_op.hpp +1 -1
  223. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_accept_op.hpp +5 -1
  224. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_connect_op.hpp +3 -1
  225. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recv_op.hpp +3 -1
  226. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recvfrom_op.hpp +3 -1
  227. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_recvmsg_op.hpp +3 -1
  228. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_send_op.hpp +3 -1
  229. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_sendto_op.hpp +3 -1
  230. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_service.hpp +41 -13
  231. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_socket_service_base.hpp +5 -4
  232. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactive_wait_op.hpp +1 -1
  233. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor.hpp +29 -5
  234. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_op.hpp +1 -1
  235. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_op_queue.hpp +1 -1
  236. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/recycling_allocator.hpp +1 -1
  237. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/regex_fwd.hpp +1 -1
  238. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolve_endpoint_op.hpp +1 -1
  239. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolve_op.hpp +1 -1
  240. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolve_query_op.hpp +1 -1
  241. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolver_service.hpp +3 -1
  242. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/resolver_service_base.hpp +1 -1
  243. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scheduler.hpp +16 -4
  244. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scheduler_operation.hpp +1 -1
  245. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scheduler_task.hpp +51 -0
  246. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scheduler_thread_info.hpp +1 -1
  247. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scoped_lock.hpp +1 -1
  248. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/scoped_ptr.hpp +1 -1
  249. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/select_interrupter.hpp +1 -1
  250. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/select_reactor.hpp +27 -1
  251. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/service_registry.hpp +1 -1
  252. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_blocker.hpp +1 -1
  253. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_handler.hpp +1 -1
  254. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_init.hpp +1 -1
  255. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_op.hpp +5 -1
  256. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/signal_set_service.hpp +57 -3
  257. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_holder.hpp +1 -1
  258. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_ops.hpp +37 -45
  259. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_option.hpp +1 -1
  260. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_select_interrupter.hpp +1 -1
  261. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/socket_types.hpp +1 -1
  262. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/solaris_fenced_block.hpp +1 -1
  263. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/source_location.hpp +1 -1
  264. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/static_mutex.hpp +1 -1
  265. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_event.hpp +1 -1
  266. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_fenced_block.hpp +1 -1
  267. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_global.hpp +1 -1
  268. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_mutex.hpp +1 -1
  269. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_static_mutex.hpp +1 -1
  270. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/std_thread.hpp +1 -1
  271. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/strand_executor_service.hpp +1 -1
  272. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/strand_service.hpp +1 -1
  273. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/string_view.hpp +1 -1
  274. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread.hpp +1 -1
  275. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread_context.hpp +1 -1
  276. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread_group.hpp +1 -1
  277. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/thread_info_base.hpp +5 -1
  278. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/throw_error.hpp +18 -9
  279. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/throw_exception.hpp +7 -3
  280. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue.hpp +1 -1
  281. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_base.hpp +1 -1
  282. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_ptime.hpp +1 -1
  283. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_queue_set.hpp +1 -1
  284. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_scheduler.hpp +3 -1
  285. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/timer_scheduler_fwd.hpp +3 -1
  286. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/tss_ptr.hpp +1 -1
  287. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/type_traits.hpp +9 -1
  288. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/utility.hpp +86 -0
  289. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/variadic_templates.hpp +1 -1
  290. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wait_handler.hpp +1 -1
  291. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wait_op.hpp +1 -1
  292. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/winsock_init.hpp +1 -1
  293. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/work_dispatcher.hpp +4 -2
  294. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/wrapped_handler.hpp +1 -1
  295. data/src/cxx_supportlib/vendor-modified/boost/asio/dispatch.hpp +126 -42
  296. data/src/cxx_supportlib/vendor-modified/boost/asio/error.hpp +30 -1
  297. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/allocator.hpp +1 -1
  298. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/any_executor.hpp +7 -2
  299. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/bad_executor.hpp +1 -1
  300. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/blocking.hpp +1 -1
  301. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/blocking_adaptation.hpp +1 -1
  302. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/bulk_execute.hpp +1 -1
  303. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/bulk_guarantee.hpp +1 -1
  304. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/connect.hpp +1 -1
  305. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/context.hpp +1 -1
  306. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/context_as.hpp +1 -1
  307. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/as_invocable.hpp +1 -1
  308. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/as_operation.hpp +1 -1
  309. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/as_receiver.hpp +1 -1
  310. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/bulk_sender.hpp +1 -1
  311. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/submit_receiver.hpp +1 -1
  312. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/detail/void_receiver.hpp +1 -1
  313. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/execute.hpp +1 -1
  314. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/executor.hpp +1 -1
  315. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/impl/bad_executor.ipp +1 -1
  316. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/impl/receiver_invocation_error.ipp +1 -1
  317. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/invocable_archetype.hpp +1 -1
  318. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/mapping.hpp +1 -1
  319. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/occupancy.hpp +1 -1
  320. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/operation_state.hpp +1 -1
  321. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/outstanding_work.hpp +1 -1
  322. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/prefer_only.hpp +1 -1
  323. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/receiver.hpp +1 -1
  324. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/receiver_invocation_error.hpp +1 -1
  325. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/relationship.hpp +1 -1
  326. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/schedule.hpp +1 -1
  327. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/scheduler.hpp +1 -1
  328. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/sender.hpp +1 -1
  329. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_done.hpp +1 -1
  330. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_error.hpp +1 -1
  331. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/set_value.hpp +1 -1
  332. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/start.hpp +1 -1
  333. data/src/cxx_supportlib/vendor-modified/boost/asio/execution/submit.hpp +1 -1
  334. data/src/cxx_supportlib/vendor-modified/boost/asio/execution.hpp +1 -1
  335. data/src/cxx_supportlib/vendor-modified/boost/asio/execution_context.hpp +1 -1
  336. data/src/cxx_supportlib/vendor-modified/boost/asio/executor.hpp +1 -1
  337. data/src/cxx_supportlib/vendor-modified/boost/asio/executor_work_guard.hpp +100 -32
  338. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/append.hpp +6 -41
  339. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/as_single.hpp +6 -5
  340. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/as_tuple.hpp +6 -101
  341. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/awaitable_operators.hpp +14 -14
  342. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/basic_channel.hpp +493 -0
  343. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/basic_concurrent_channel.hpp +493 -0
  344. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/cancellation_condition.hpp +1 -1
  345. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/channel.hpp +72 -0
  346. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/channel_error.hpp +88 -0
  347. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/channel_traits.hpp +233 -0
  348. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/co_spawn.hpp +189 -0
  349. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/concurrent_channel.hpp +72 -0
  350. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/coro.hpp +95 -887
  351. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/{detail/coro_traits.hpp → coro_traits.hpp} +65 -20
  352. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/deferred.hpp +6 -575
  353. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_handler.hpp +72 -0
  354. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_message.hpp +124 -0
  355. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_operation.hpp +201 -0
  356. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_payload.hpp +95 -0
  357. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_receive_op.hpp +114 -0
  358. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_send_functions.hpp +134 -0
  359. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_send_op.hpp +142 -0
  360. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/channel_service.hpp +499 -0
  361. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/completion_handler_erasure.hpp +82 -46
  362. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/coro_promise_allocator.hpp +3 -3
  363. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/has_signature.hpp +56 -0
  364. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/impl/channel_service.hpp +611 -0
  365. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/detail/partial_promise.hpp +11 -12
  366. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/as_single.hpp +1 -1
  367. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/channel_error.ipp +63 -0
  368. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/coro.hpp +1197 -0
  369. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/parallel_group.hpp +14 -28
  370. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/promise.hpp +6 -2
  371. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/impl/use_coro.hpp +270 -0
  372. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/parallel_group.hpp +27 -37
  373. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/prepend.hpp +6 -41
  374. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/promise.hpp +27 -405
  375. data/src/cxx_supportlib/vendor-modified/boost/asio/experimental/use_coro.hpp +116 -229
  376. data/src/cxx_supportlib/vendor-modified/boost/asio/file_base.hpp +168 -0
  377. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/basic_endpoint.hpp +1 -1
  378. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/datagram_protocol.hpp +1 -1
  379. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/detail/endpoint.hpp +1 -1
  380. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/detail/impl/endpoint.ipp +1 -1
  381. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/raw_protocol.hpp +1 -1
  382. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/seq_packet_protocol.hpp +1 -1
  383. data/src/cxx_supportlib/vendor-modified/boost/asio/generic/stream_protocol.hpp +1 -1
  384. data/src/cxx_supportlib/vendor-modified/boost/asio/handler_alloc_hook.hpp +1 -1
  385. data/src/cxx_supportlib/vendor-modified/boost/asio/handler_continuation_hook.hpp +1 -1
  386. data/src/cxx_supportlib/vendor-modified/boost/asio/handler_invoke_hook.hpp +1 -1
  387. data/src/cxx_supportlib/vendor-modified/boost/asio/high_resolution_timer.hpp +1 -1
  388. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/any_io_executor.ipp +131 -0
  389. data/src/cxx_supportlib/vendor-modified/boost/asio/{experimental/impl → impl}/append.hpp +18 -19
  390. data/src/cxx_supportlib/vendor-modified/boost/asio/{experimental/impl → impl}/as_tuple.hpp +13 -15
  391. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/awaitable.hpp +400 -5
  392. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_read_stream.hpp +13 -3
  393. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/buffered_write_stream.hpp +13 -3
  394. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/cancellation_signal.ipp +98 -0
  395. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/co_spawn.hpp +71 -7
  396. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/compose.hpp +21 -1
  397. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/connect.hpp +67 -34
  398. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/connect_pipe.hpp +75 -0
  399. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/connect_pipe.ipp +151 -0
  400. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/defer.hpp +23 -13
  401. data/src/cxx_supportlib/vendor-modified/boost/asio/{experimental/impl → impl}/deferred.hpp +31 -40
  402. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/detached.hpp +1 -1
  403. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/dispatch.hpp +23 -13
  404. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/error.ipp +1 -1
  405. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/execution_context.hpp +1 -1
  406. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/execution_context.ipp +1 -1
  407. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/executor.hpp +1 -1
  408. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/executor.ipp +1 -1
  409. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/handler_alloc_hook.ipp +1 -1
  410. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/io_context.hpp +53 -47
  411. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/io_context.ipp +1 -1
  412. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/multiple_exceptions.ipp +1 -1
  413. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/post.hpp +23 -13
  414. data/src/cxx_supportlib/vendor-modified/boost/asio/{experimental/impl → impl}/prepend.hpp +16 -17
  415. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read.hpp +97 -51
  416. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_at.hpp +51 -31
  417. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/read_until.hpp +119 -59
  418. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/redirect_error.hpp +1 -1
  419. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/serial_port_base.hpp +1 -1
  420. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/serial_port_base.ipp +1 -1
  421. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/spawn.hpp +1321 -277
  422. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/src.hpp +11 -2
  423. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/system_context.hpp +1 -1
  424. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/system_context.ipp +1 -1
  425. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/system_executor.hpp +1 -1
  426. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/thread_pool.hpp +1 -1
  427. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/thread_pool.ipp +1 -1
  428. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/use_awaitable.hpp +18 -8
  429. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/use_future.hpp +1 -1
  430. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write.hpp +95 -50
  431. data/src/cxx_supportlib/vendor-modified/boost/asio/impl/write_at.hpp +53 -31
  432. data/src/cxx_supportlib/vendor-modified/boost/asio/io_context.hpp +111 -114
  433. data/src/cxx_supportlib/vendor-modified/boost/asio/io_context_strand.hpp +15 -3
  434. data/src/cxx_supportlib/vendor-modified/boost/asio/io_service.hpp +1 -1
  435. data/src/cxx_supportlib/vendor-modified/boost/asio/io_service_strand.hpp +1 -1
  436. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address.hpp +1 -1
  437. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v4.hpp +75 -1
  438. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v4_iterator.hpp +1 -1
  439. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v4_range.hpp +1 -1
  440. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v6.hpp +35 -1
  441. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v6_iterator.hpp +1 -1
  442. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/address_v6_range.hpp +1 -1
  443. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/bad_address_cast.hpp +1 -1
  444. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_endpoint.hpp +1 -1
  445. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver.hpp +130 -64
  446. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_entry.hpp +1 -1
  447. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_iterator.hpp +1 -1
  448. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_query.hpp +1 -1
  449. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/basic_resolver_results.hpp +1 -1
  450. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/endpoint.hpp +1 -1
  451. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/impl/endpoint.ipp +1 -1
  452. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/detail/socket_option.hpp +1 -1
  453. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/host_name.hpp +1 -1
  454. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/icmp.hpp +1 -1
  455. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address.hpp +1 -1
  456. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address.ipp +1 -1
  457. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v4.hpp +1 -1
  458. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v4.ipp +1 -1
  459. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v6.hpp +1 -1
  460. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/address_v6.ipp +1 -1
  461. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/basic_endpoint.hpp +1 -1
  462. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/host_name.ipp +1 -1
  463. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v4.hpp +1 -1
  464. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v4.ipp +1 -1
  465. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v6.hpp +1 -1
  466. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/impl/network_v6.ipp +1 -1
  467. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/multicast.hpp +1 -1
  468. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/network_v4.hpp +2 -2
  469. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/network_v6.hpp +1 -1
  470. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/resolver_base.hpp +1 -1
  471. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/resolver_query_base.hpp +1 -1
  472. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/tcp.hpp +1 -1
  473. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/udp.hpp +1 -1
  474. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/unicast.hpp +1 -1
  475. data/src/cxx_supportlib/vendor-modified/boost/asio/ip/v6_only.hpp +2 -2
  476. data/src/cxx_supportlib/vendor-modified/boost/asio/is_applicable_property.hpp +1 -1
  477. data/src/cxx_supportlib/vendor-modified/boost/asio/is_contiguous_iterator.hpp +47 -0
  478. data/src/cxx_supportlib/vendor-modified/boost/asio/is_executor.hpp +1 -1
  479. data/src/cxx_supportlib/vendor-modified/boost/asio/is_read_buffered.hpp +1 -1
  480. data/src/cxx_supportlib/vendor-modified/boost/asio/is_write_buffered.hpp +1 -1
  481. data/src/cxx_supportlib/vendor-modified/boost/asio/local/basic_endpoint.hpp +1 -1
  482. data/src/cxx_supportlib/vendor-modified/boost/asio/local/connect_pair.hpp +1 -1
  483. data/src/cxx_supportlib/vendor-modified/boost/asio/local/datagram_protocol.hpp +1 -1
  484. data/src/cxx_supportlib/vendor-modified/boost/asio/local/detail/endpoint.hpp +1 -1
  485. data/src/cxx_supportlib/vendor-modified/boost/asio/local/detail/impl/endpoint.ipp +1 -1
  486. data/src/cxx_supportlib/vendor-modified/boost/asio/local/stream_protocol.hpp +1 -1
  487. data/src/cxx_supportlib/vendor-modified/boost/asio/multiple_exceptions.hpp +1 -1
  488. data/src/cxx_supportlib/vendor-modified/boost/asio/packaged_task.hpp +1 -1
  489. data/src/cxx_supportlib/vendor-modified/boost/asio/placeholders.hpp +1 -1
  490. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_descriptor.hpp +89 -16
  491. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/basic_stream_descriptor.hpp +95 -27
  492. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/descriptor.hpp +1 -1
  493. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/descriptor_base.hpp +1 -1
  494. data/src/cxx_supportlib/vendor-modified/boost/asio/posix/stream_descriptor.hpp +1 -1
  495. data/src/cxx_supportlib/vendor-modified/boost/asio/post.hpp +128 -42
  496. data/src/cxx_supportlib/vendor-modified/boost/asio/prefer.hpp +1 -1
  497. data/src/cxx_supportlib/vendor-modified/boost/asio/prepend.hpp +80 -0
  498. data/src/cxx_supportlib/vendor-modified/boost/asio/query.hpp +1 -1
  499. data/src/cxx_supportlib/vendor-modified/boost/asio/random_access_file.hpp +37 -0
  500. data/src/cxx_supportlib/vendor-modified/boost/asio/read.hpp +245 -153
  501. data/src/cxx_supportlib/vendor-modified/boost/asio/read_at.hpp +110 -53
  502. data/src/cxx_supportlib/vendor-modified/boost/asio/read_until.hpp +301 -166
  503. data/src/cxx_supportlib/vendor-modified/boost/asio/readable_pipe.hpp +37 -0
  504. data/src/cxx_supportlib/vendor-modified/boost/asio/recycling_allocator.hpp +140 -0
  505. data/src/cxx_supportlib/vendor-modified/boost/asio/redirect_error.hpp +3 -3
  506. data/src/cxx_supportlib/vendor-modified/boost/asio/registered_buffer.hpp +358 -0
  507. data/src/cxx_supportlib/vendor-modified/boost/asio/require.hpp +1 -1
  508. data/src/cxx_supportlib/vendor-modified/boost/asio/require_concept.hpp +1 -1
  509. data/src/cxx_supportlib/vendor-modified/boost/asio/serial_port.hpp +1 -1
  510. data/src/cxx_supportlib/vendor-modified/boost/asio/serial_port_base.hpp +1 -1
  511. data/src/cxx_supportlib/vendor-modified/boost/asio/signal_set.hpp +1 -1
  512. data/src/cxx_supportlib/vendor-modified/boost/asio/socket_base.hpp +1 -1
  513. data/src/cxx_supportlib/vendor-modified/boost/asio/spawn.hpp +647 -87
  514. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/context.hpp +4 -1
  515. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/context_base.hpp +1 -1
  516. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/buffered_handshake_op.hpp +1 -1
  517. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/engine.hpp +4 -1
  518. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/handshake_op.hpp +1 -1
  519. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/impl/engine.ipp +19 -1
  520. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/impl/openssl_init.ipp +7 -3
  521. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/io.hpp +1 -1
  522. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/openssl_init.hpp +1 -1
  523. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/openssl_types.hpp +1 -1
  524. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/password_callback.hpp +1 -1
  525. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/read_op.hpp +1 -1
  526. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/shutdown_op.hpp +1 -1
  527. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/stream_core.hpp +16 -1
  528. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/verify_callback.hpp +1 -1
  529. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/detail/write_op.hpp +1 -1
  530. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/error.hpp +1 -1
  531. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/host_name_verification.hpp +1 -1
  532. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/context.hpp +1 -1
  533. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/context.ipp +140 -64
  534. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/error.ipp +25 -3
  535. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/host_name_verification.ipp +1 -1
  536. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/rfc2818_verification.ipp +1 -1
  537. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/impl/src.hpp +1 -1
  538. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/rfc2818_verification.hpp +1 -1
  539. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/stream.hpp +154 -53
  540. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/stream_base.hpp +1 -1
  541. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/verify_context.hpp +1 -1
  542. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl/verify_mode.hpp +1 -1
  543. data/src/cxx_supportlib/vendor-modified/boost/asio/ssl.hpp +1 -1
  544. data/src/cxx_supportlib/vendor-modified/boost/asio/static_thread_pool.hpp +1 -1
  545. data/src/cxx_supportlib/vendor-modified/boost/asio/steady_timer.hpp +1 -1
  546. data/src/cxx_supportlib/vendor-modified/boost/asio/strand.hpp +12 -1
  547. data/src/cxx_supportlib/vendor-modified/boost/asio/stream_file.hpp +37 -0
  548. data/src/cxx_supportlib/vendor-modified/boost/asio/streambuf.hpp +1 -1
  549. data/src/cxx_supportlib/vendor-modified/boost/asio/system_context.hpp +1 -1
  550. data/src/cxx_supportlib/vendor-modified/boost/asio/system_executor.hpp +1 -1
  551. data/src/cxx_supportlib/vendor-modified/boost/asio/system_timer.hpp +1 -1
  552. data/src/cxx_supportlib/vendor-modified/boost/asio/this_coro.hpp +11 -11
  553. data/src/cxx_supportlib/vendor-modified/boost/asio/thread_pool.hpp +10 -1
  554. data/src/cxx_supportlib/vendor-modified/boost/asio/time_traits.hpp +1 -1
  555. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/bulk_execute_free.hpp +1 -1
  556. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/bulk_execute_member.hpp +1 -1
  557. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/connect_free.hpp +1 -1
  558. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/connect_member.hpp +1 -1
  559. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/equality_comparable.hpp +1 -1
  560. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/execute_free.hpp +1 -1
  561. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/execute_member.hpp +1 -1
  562. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/prefer_free.hpp +1 -1
  563. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/prefer_member.hpp +1 -1
  564. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/query_free.hpp +1 -1
  565. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/query_member.hpp +1 -1
  566. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/query_static_constexpr_member.hpp +1 -1
  567. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/require_concept_free.hpp +1 -1
  568. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/require_concept_member.hpp +1 -1
  569. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/require_free.hpp +1 -1
  570. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/require_member.hpp +1 -1
  571. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/schedule_free.hpp +1 -1
  572. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/schedule_member.hpp +1 -1
  573. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_done_free.hpp +1 -1
  574. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_done_member.hpp +1 -1
  575. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_error_free.hpp +1 -1
  576. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_error_member.hpp +1 -1
  577. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_value_free.hpp +1 -1
  578. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/set_value_member.hpp +1 -1
  579. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/start_free.hpp +1 -1
  580. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/start_member.hpp +1 -1
  581. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/static_query.hpp +1 -1
  582. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/static_require.hpp +1 -1
  583. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/static_require_concept.hpp +1 -1
  584. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/submit_free.hpp +1 -1
  585. data/src/cxx_supportlib/vendor-modified/boost/asio/traits/submit_member.hpp +1 -1
  586. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/buffer.hpp +1 -1
  587. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/executor.hpp +1 -1
  588. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/internet.hpp +1 -1
  589. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/io_context.hpp +1 -1
  590. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/net.hpp +1 -1
  591. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/netfwd.hpp +1 -1
  592. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/socket.hpp +1 -1
  593. data/src/cxx_supportlib/vendor-modified/boost/asio/ts/timer.hpp +1 -1
  594. data/src/cxx_supportlib/vendor-modified/boost/asio/unyield.hpp +1 -1
  595. data/src/cxx_supportlib/vendor-modified/boost/asio/use_awaitable.hpp +4 -3
  596. data/src/cxx_supportlib/vendor-modified/boost/asio/use_future.hpp +10 -7
  597. data/src/cxx_supportlib/vendor-modified/boost/asio/uses_executor.hpp +1 -1
  598. data/src/cxx_supportlib/vendor-modified/boost/asio/version.hpp +2 -2
  599. data/src/cxx_supportlib/vendor-modified/boost/asio/wait_traits.hpp +1 -1
  600. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_object_handle.hpp +70 -12
  601. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_overlapped_handle.hpp +100 -1
  602. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_random_access_handle.hpp +98 -29
  603. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/basic_stream_handle.hpp +95 -28
  604. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/object_handle.hpp +1 -1
  605. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/overlapped_handle.hpp +1 -1
  606. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/overlapped_ptr.hpp +1 -1
  607. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/random_access_handle.hpp +1 -1
  608. data/src/cxx_supportlib/vendor-modified/boost/asio/windows/stream_handle.hpp +1 -1
  609. data/src/cxx_supportlib/vendor-modified/boost/asio/writable_pipe.hpp +37 -0
  610. data/src/cxx_supportlib/vendor-modified/boost/asio/write.hpp +242 -150
  611. data/src/cxx_supportlib/vendor-modified/boost/asio/write_at.hpp +112 -53
  612. data/src/cxx_supportlib/vendor-modified/boost/asio/yield.hpp +1 -1
  613. data/src/cxx_supportlib/vendor-modified/boost/asio.hpp +21 -1
  614. data/src/cxx_supportlib/vendor-modified/boost/assert/source_location.hpp +115 -25
  615. data/src/cxx_supportlib/vendor-modified/boost/atomic/atomic.hpp +8 -2
  616. data/src/cxx_supportlib/vendor-modified/boost/atomic/atomic_ref.hpp +2 -2
  617. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/addressof.hpp +5 -1
  618. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_impl.hpp +183 -64
  619. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/atomic_ref_impl.hpp +166 -66
  620. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_cast.hpp +80 -11
  621. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/bitwise_fp_cast.hpp +40 -11
  622. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_arch_gcc_aarch32.hpp +8 -1
  623. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_arch_gcc_aarch64.hpp +8 -1
  624. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/caps_arch_gcc_arm.hpp +8 -1
  625. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/classify.hpp +19 -10
  626. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/config.hpp +19 -5
  627. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/core_arch_ops_gcc_ppc.hpp +105 -100
  628. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_fp_ops_generic.hpp +1 -1
  629. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/extra_ops_gcc_ppc.hpp +73 -72
  630. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/futex.hpp +8 -1
  631. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/gcc_arm_asm_common.hpp +4 -0
  632. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/gcc_ppc_asm_common.hpp +33 -0
  633. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/platform.hpp +15 -6
  634. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/alignment_of.hpp +3 -3
  635. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/has_unique_object_representations.hpp +143 -0
  636. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_enum.hpp +42 -0
  637. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/type_traits/is_nothrow_default_constructible.hpp +46 -0
  638. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_caps_darwin_ulock.hpp +58 -0
  639. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_caps_windows.hpp +3 -1
  640. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_on_address.hpp +65 -0
  641. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_darwin_ulock.hpp +158 -0
  642. data/src/cxx_supportlib/vendor-modified/boost/atomic/detail/wait_ops_windows.hpp +55 -26
  643. data/src/cxx_supportlib/vendor-modified/boost/atomic/ipc_atomic.hpp +8 -2
  644. data/src/cxx_supportlib/vendor-modified/boost/atomic/ipc_atomic_ref.hpp +2 -2
  645. data/src/cxx_supportlib/vendor-modified/boost/bind/bind.hpp +1 -1
  646. data/src/cxx_supportlib/vendor-modified/boost/bind/detail/result_traits.hpp +12 -2
  647. data/src/cxx_supportlib/vendor-modified/boost/bind/protect.hpp +1 -1
  648. data/src/cxx_supportlib/vendor-modified/boost/chrono/duration.hpp +6 -3
  649. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_io.hpp +1 -1
  650. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/duration_style.hpp +1 -1
  651. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/time_point_io.hpp +1 -1
  652. data/src/cxx_supportlib/vendor-modified/boost/chrono/io/timezone.hpp +2 -1
  653. data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx03.hpp +1 -1
  654. data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx11.hpp +1 -4
  655. data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx14.hpp +1 -1
  656. data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx17.hpp +4 -1
  657. data/src/cxx_supportlib/vendor-modified/boost/config/assert_cxx20.hpp +4 -1
  658. data/src/cxx_supportlib/vendor-modified/boost/config/auto_link.hpp +6 -1
  659. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang.hpp +2 -0
  660. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/clang_version.hpp +77 -0
  661. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/gcc.hpp +3 -2
  662. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/nvcc.hpp +3 -0
  663. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/visualc.hpp +2 -0
  664. data/src/cxx_supportlib/vendor-modified/boost/config/compiler/xlcpp.hpp +1 -0
  665. data/src/cxx_supportlib/vendor-modified/boost/config/detail/cxx_composite.hpp +4 -3
  666. data/src/cxx_supportlib/vendor-modified/boost/config/detail/suffix.hpp +51 -35
  667. data/src/cxx_supportlib/vendor-modified/boost/config/platform/wasm.hpp +6 -0
  668. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/dinkumware.hpp +14 -19
  669. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libcpp.hpp +2 -45
  670. data/src/cxx_supportlib/vendor-modified/boost/config/stdlib/libstdcpp3.hpp +23 -1
  671. data/src/cxx_supportlib/vendor-modified/boost/config/workaround.hpp +11 -0
  672. data/src/cxx_supportlib/vendor-modified/boost/container/adaptive_pool.hpp +12 -6
  673. data/src/cxx_supportlib/vendor-modified/boost/container/allocator.hpp +8 -3
  674. data/src/cxx_supportlib/vendor-modified/boost/container/container_fwd.hpp +1 -3
  675. data/src/cxx_supportlib/vendor-modified/boost/container/deque.hpp +70 -59
  676. data/src/cxx_supportlib/vendor-modified/boost/container/detail/adaptive_node_pool_impl.hpp +6 -5
  677. data/src/cxx_supportlib/vendor-modified/boost/container/detail/addressof.hpp +2 -10
  678. data/src/cxx_supportlib/vendor-modified/boost/container/detail/advanced_insert_int.hpp +31 -40
  679. data/src/cxx_supportlib/vendor-modified/boost/container/detail/compare_functors.hpp +13 -10
  680. data/src/cxx_supportlib/vendor-modified/boost/container/detail/construct_in_place.hpp +17 -15
  681. data/src/cxx_supportlib/vendor-modified/boost/container/detail/copy_move_algo.hpp +87 -84
  682. data/src/cxx_supportlib/vendor-modified/boost/container/detail/destroyers.hpp +59 -32
  683. data/src/cxx_supportlib/vendor-modified/boost/container/detail/dispatch_uses_allocator.hpp +3 -1
  684. data/src/cxx_supportlib/vendor-modified/boost/container/detail/flat_tree.hpp +46 -35
  685. data/src/cxx_supportlib/vendor-modified/boost/container/detail/hash_table.hpp +1278 -0
  686. data/src/cxx_supportlib/vendor-modified/boost/container/detail/is_pair.hpp +91 -0
  687. data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterator.hpp +6 -0
  688. data/src/cxx_supportlib/vendor-modified/boost/container/detail/iterators.hpp +88 -69
  689. data/src/cxx_supportlib/vendor-modified/boost/container/detail/multiallocation_chain.hpp +2 -2
  690. data/src/cxx_supportlib/vendor-modified/boost/container/detail/next_capacity.hpp +2 -2
  691. data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_alloc_holder.hpp +240 -105
  692. data/src/cxx_supportlib/vendor-modified/boost/container/detail/node_pool_impl.hpp +2 -1
  693. data/src/cxx_supportlib/vendor-modified/boost/container/detail/pair.hpp +19 -91
  694. data/src/cxx_supportlib/vendor-modified/boost/container/detail/placement_new.hpp +2 -0
  695. data/src/cxx_supportlib/vendor-modified/boost/container/detail/pool_resource.hpp +3 -7
  696. data/src/cxx_supportlib/vendor-modified/boost/container/detail/transform_iterator.hpp +28 -28
  697. data/src/cxx_supportlib/vendor-modified/boost/container/detail/tree.hpp +118 -244
  698. data/src/cxx_supportlib/vendor-modified/boost/container/detail/type_traits.hpp +1 -0
  699. data/src/cxx_supportlib/vendor-modified/boost/container/detail/workaround.hpp +5 -10
  700. data/src/cxx_supportlib/vendor-modified/boost/container/devector.hpp +66 -38
  701. data/src/cxx_supportlib/vendor-modified/boost/container/flat_map.hpp +28 -9
  702. data/src/cxx_supportlib/vendor-modified/boost/container/flat_set.hpp +27 -8
  703. data/src/cxx_supportlib/vendor-modified/boost/container/list.hpp +14 -71
  704. data/src/cxx_supportlib/vendor-modified/boost/container/map.hpp +11 -8
  705. data/src/cxx_supportlib/vendor-modified/boost/container/new_allocator.hpp +9 -2
  706. data/src/cxx_supportlib/vendor-modified/boost/container/node_allocator.hpp +1 -1
  707. data/src/cxx_supportlib/vendor-modified/boost/container/node_handle.hpp +3 -3
  708. data/src/cxx_supportlib/vendor-modified/boost/container/options.hpp +23 -6
  709. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/memory_resource.hpp +6 -1
  710. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/monotonic_buffer_resource.hpp +3 -3
  711. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/resource_adaptor.hpp +3 -3
  712. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/synchronized_pool_resource.hpp +3 -3
  713. data/src/cxx_supportlib/vendor-modified/boost/container/pmr/unsynchronized_pool_resource.hpp +3 -3
  714. data/src/cxx_supportlib/vendor-modified/boost/container/set.hpp +11 -8
  715. data/src/cxx_supportlib/vendor-modified/boost/container/slist.hpp +32 -87
  716. data/src/cxx_supportlib/vendor-modified/boost/container/small_vector.hpp +100 -147
  717. data/src/cxx_supportlib/vendor-modified/boost/container/stable_vector.hpp +41 -35
  718. data/src/cxx_supportlib/vendor-modified/boost/container/static_vector.hpp +74 -46
  719. data/src/cxx_supportlib/vendor-modified/boost/container/string.hpp +207 -187
  720. data/src/cxx_supportlib/vendor-modified/boost/container/throw_exception.hpp +2 -2
  721. data/src/cxx_supportlib/vendor-modified/boost/container/vector.hpp +86 -71
  722. data/src/cxx_supportlib/vendor-modified/boost/container_hash/hash.hpp +40 -35
  723. data/src/cxx_supportlib/vendor-modified/boost/core/alloc_construct.hpp +7 -81
  724. data/src/cxx_supportlib/vendor-modified/boost/core/allocator_access.hpp +426 -207
  725. data/src/cxx_supportlib/vendor-modified/boost/core/allocator_traits.hpp +112 -0
  726. data/src/cxx_supportlib/vendor-modified/boost/core/bit.hpp +28 -14
  727. data/src/cxx_supportlib/vendor-modified/boost/core/cmath.hpp +100 -1
  728. data/src/cxx_supportlib/vendor-modified/boost/core/default_allocator.hpp +19 -9
  729. data/src/cxx_supportlib/vendor-modified/boost/core/detail/splitmix64.hpp +3 -3
  730. data/src/cxx_supportlib/vendor-modified/boost/core/detail/string_view.hpp +1256 -0
  731. data/src/cxx_supportlib/vendor-modified/boost/core/empty_value.hpp +9 -0
  732. data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test.hpp +7 -1
  733. data/src/cxx_supportlib/vendor-modified/boost/core/lightweight_test_trait.hpp +5 -51
  734. data/src/cxx_supportlib/vendor-modified/boost/core/noinit_adaptor.hpp +3 -0
  735. data/src/cxx_supportlib/vendor-modified/boost/core/noncopyable.hpp +1 -1
  736. data/src/cxx_supportlib/vendor-modified/boost/core/pointer_traits.hpp +111 -60
  737. data/src/cxx_supportlib/vendor-modified/boost/core/quick_exit.hpp +1 -1
  738. data/src/cxx_supportlib/vendor-modified/boost/core/span.hpp +399 -0
  739. data/src/cxx_supportlib/vendor-modified/boost/core/type_name.hpp +1157 -0
  740. data/src/cxx_supportlib/vendor-modified/boost/core/verbose_terminate_handler.hpp +88 -0
  741. data/src/cxx_supportlib/vendor-modified/boost/date_time/gregorian_calendar.ipp +1 -1
  742. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/conversion.hpp +1 -1
  743. data/src/cxx_supportlib/vendor-modified/boost/date_time/posix_time/posix_time_io.hpp +1 -1
  744. data/src/cxx_supportlib/vendor-modified/boost/detail/workaround.hpp +3 -3
  745. data/src/cxx_supportlib/vendor-modified/boost/exception/detail/exception_ptr.hpp +38 -22
  746. data/src/cxx_supportlib/vendor-modified/boost/exception/exception.hpp +84 -2
  747. data/src/cxx_supportlib/vendor-modified/boost/exception/info.hpp +1 -1
  748. data/src/cxx_supportlib/vendor-modified/boost/function/function_base.hpp +9 -0
  749. data/src/cxx_supportlib/vendor-modified/boost/function/function_template.hpp +16 -0
  750. data/src/cxx_supportlib/vendor-modified/boost/integer/integer_log2.hpp +85 -80
  751. data/src/cxx_supportlib/vendor-modified/boost/intrusive/avltree_algorithms.hpp +39 -39
  752. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree.hpp +27 -27
  753. data/src/cxx_supportlib/vendor-modified/boost/intrusive/bstree_algorithms.hpp +37 -40
  754. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_list_algorithms.hpp +24 -15
  755. data/src/cxx_supportlib/vendor-modified/boost/intrusive/circular_slist_algorithms.hpp +75 -6
  756. data/src/cxx_supportlib/vendor-modified/boost/intrusive/derivation_value_traits.hpp +2 -2
  757. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/any_node_and_algorithms.hpp +25 -25
  758. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/array_initializer.hpp +3 -2
  759. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/avltree_node.hpp +14 -14
  760. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/bstree_algorithms_base.hpp +4 -4
  761. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/common_slist_algorithms.hpp +76 -7
  762. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/default_header_holder.hpp +1 -1
  763. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/empty_node_checker.hpp +1 -1
  764. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/exception_disposer.hpp +0 -31
  765. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hashtable_node.hpp +182 -102
  766. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/hook_traits.hpp +8 -8
  767. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/iterator.hpp +106 -76
  768. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_iterator.hpp +3 -3
  769. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/list_node.hpp +4 -4
  770. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/math.hpp +3 -3
  771. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/mpl.hpp +1 -1
  772. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/node_cloner_disposer.hpp +3 -3
  773. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/node_to_value.hpp +1 -1
  774. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/rbtree_node.hpp +18 -18
  775. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/reverse_iterator.hpp +3 -140
  776. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/simple_disposers.hpp +1 -1
  777. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_iterator.hpp +11 -4
  778. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/slist_node.hpp +2 -2
  779. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_iterator.hpp +2 -2
  780. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/tree_node.hpp +6 -6
  781. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/value_functors.hpp +10 -0
  782. data/src/cxx_supportlib/vendor-modified/boost/intrusive/detail/workaround.hpp +3 -3
  783. data/src/cxx_supportlib/vendor-modified/boost/intrusive/hashtable.hpp +1525 -882
  784. data/src/cxx_supportlib/vendor-modified/boost/intrusive/intrusive_fwd.hpp +2 -0
  785. data/src/cxx_supportlib/vendor-modified/boost/intrusive/linear_slist_algorithms.hpp +81 -8
  786. data/src/cxx_supportlib/vendor-modified/boost/intrusive/list.hpp +9 -8
  787. data/src/cxx_supportlib/vendor-modified/boost/intrusive/member_value_traits.hpp +2 -2
  788. data/src/cxx_supportlib/vendor-modified/boost/intrusive/options.hpp +17 -3
  789. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pack_options.hpp +10 -8
  790. data/src/cxx_supportlib/vendor-modified/boost/intrusive/pointer_traits.hpp +12 -4
  791. data/src/cxx_supportlib/vendor-modified/boost/intrusive/priority_compare.hpp +9 -2
  792. data/src/cxx_supportlib/vendor-modified/boost/intrusive/rbtree_algorithms.hpp +36 -36
  793. data/src/cxx_supportlib/vendor-modified/boost/intrusive/sgtree_algorithms.hpp +16 -16
  794. data/src/cxx_supportlib/vendor-modified/boost/intrusive/slist.hpp +32 -35
  795. data/src/cxx_supportlib/vendor-modified/boost/intrusive/splaytree_algorithms.hpp +27 -27
  796. data/src/cxx_supportlib/vendor-modified/boost/intrusive/treap_algorithms.hpp +14 -14
  797. data/src/cxx_supportlib/vendor-modified/boost/intrusive/trivial_value_traits.hpp +2 -2
  798. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set.hpp +27 -20
  799. data/src/cxx_supportlib/vendor-modified/boost/intrusive/unordered_set_hook.hpp +6 -6
  800. data/src/cxx_supportlib/vendor-modified/boost/iterator/advance.hpp +11 -0
  801. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/config_def.hpp +6 -6
  802. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/config_undef.hpp +1 -1
  803. data/src/cxx_supportlib/vendor-modified/boost/iterator/detail/enable_if.hpp +5 -5
  804. data/src/cxx_supportlib/vendor-modified/boost/iterator/transform_iterator.hpp +8 -4
  805. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/bad_lexical_cast.hpp +1 -1
  806. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical.hpp +1 -1
  807. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_lexical_streams.hpp +1 -1
  808. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/converter_numeric.hpp +1 -1
  809. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/inf_nan.hpp +1 -1
  810. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/is_character.hpp +1 -1
  811. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_char_constants.hpp +1 -1
  812. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/lcast_unsigned_converters.hpp +1 -1
  813. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/detail/widest_char.hpp +1 -1
  814. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast/try_lexical_convert.hpp +1 -1
  815. data/src/cxx_supportlib/vendor-modified/boost/lexical_cast.hpp +1 -1
  816. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_merge.hpp +43 -30
  817. data/src/cxx_supportlib/vendor-modified/boost/move/algo/adaptive_sort.hpp +72 -56
  818. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/adaptive_sort_merge.hpp +172 -128
  819. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/heap_sort.hpp +19 -9
  820. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/insertion_sort.hpp +9 -0
  821. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge.hpp +108 -146
  822. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/merge_sort.hpp +24 -15
  823. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/pdqsort.hpp +14 -4
  824. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/search.hpp +79 -0
  825. data/src/cxx_supportlib/vendor-modified/boost/move/algo/detail/set_difference.hpp +8 -2
  826. data/src/cxx_supportlib/vendor-modified/boost/move/algo/move.hpp +4 -0
  827. data/src/cxx_supportlib/vendor-modified/boost/move/algo/predicate.hpp +10 -10
  828. data/src/cxx_supportlib/vendor-modified/boost/move/core.hpp +21 -0
  829. data/src/cxx_supportlib/vendor-modified/boost/move/detail/addressof.hpp +61 -0
  830. data/src/cxx_supportlib/vendor-modified/boost/move/detail/force_ptr.hpp +36 -0
  831. data/src/cxx_supportlib/vendor-modified/boost/move/detail/iterator_traits.hpp +108 -9
  832. data/src/cxx_supportlib/vendor-modified/boost/move/detail/meta_utils.hpp +8 -32
  833. data/src/cxx_supportlib/vendor-modified/boost/move/detail/nsec_clock.hpp +6 -3
  834. data/src/cxx_supportlib/vendor-modified/boost/move/detail/reverse_iterator.hpp +40 -33
  835. data/src/cxx_supportlib/vendor-modified/boost/move/detail/std_ns_begin.hpp +5 -1
  836. data/src/cxx_supportlib/vendor-modified/boost/move/detail/std_ns_end.hpp +2 -0
  837. data/src/cxx_supportlib/vendor-modified/boost/move/detail/type_traits.hpp +1 -2
  838. data/src/cxx_supportlib/vendor-modified/boost/move/detail/workaround.hpp +5 -3
  839. data/src/cxx_supportlib/vendor-modified/boost/move/make_unique.hpp +10 -0
  840. data/src/cxx_supportlib/vendor-modified/boost/move/utility_core.hpp +31 -28
  841. data/src/cxx_supportlib/vendor-modified/boost/mp11/algorithm.hpp +1306 -0
  842. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/config.hpp +138 -0
  843. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_append.hpp +185 -0
  844. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_copy_if.hpp +48 -0
  845. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_count.hpp +147 -0
  846. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_fold.hpp +62 -0
  847. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_front.hpp +38 -0
  848. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_is_list.hpp +39 -0
  849. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_list.hpp +24 -0
  850. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_map_find.hpp +87 -0
  851. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_min_element.hpp +51 -0
  852. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_plus.hpp +81 -0
  853. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_remove_if.hpp +48 -0
  854. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_rename.hpp +41 -0
  855. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_void.hpp +32 -0
  856. data/src/cxx_supportlib/vendor-modified/boost/mp11/detail/mp_with_index.hpp +385 -0
  857. data/src/cxx_supportlib/vendor-modified/boost/mp11/function.hpp +222 -0
  858. data/src/cxx_supportlib/vendor-modified/boost/mp11/integer_sequence.hpp +112 -0
  859. data/src/cxx_supportlib/vendor-modified/boost/mp11/integral.hpp +41 -0
  860. data/src/cxx_supportlib/vendor-modified/boost/mp11/list.hpp +304 -0
  861. data/src/cxx_supportlib/vendor-modified/boost/mp11/set.hpp +188 -0
  862. data/src/cxx_supportlib/vendor-modified/boost/mp11/utility.hpp +263 -0
  863. data/src/cxx_supportlib/vendor-modified/boost/mp11/version.hpp +16 -0
  864. data/src/cxx_supportlib/vendor-modified/boost/mpl/and.hpp +1 -1
  865. data/src/cxx_supportlib/vendor-modified/boost/mpl/assert.hpp +3 -3
  866. data/src/cxx_supportlib/vendor-modified/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp +1 -1
  867. data/src/cxx_supportlib/vendor-modified/boost/mpl/aux_/template_arity.hpp +1 -1
  868. data/src/cxx_supportlib/vendor-modified/boost/mpl/aux_/yes_no.hpp +2 -1
  869. data/src/cxx_supportlib/vendor-modified/boost/mpl/bitand.hpp +1 -1
  870. data/src/cxx_supportlib/vendor-modified/boost/mpl/bitor.hpp +1 -1
  871. data/src/cxx_supportlib/vendor-modified/boost/mpl/or.hpp +1 -1
  872. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_aligned_storage.hpp +1 -1
  873. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_hash.hpp +49 -0
  874. data/src/cxx_supportlib/vendor-modified/boost/optional/detail/optional_trivially_copyable_base.hpp +34 -23
  875. data/src/cxx_supportlib/vendor-modified/boost/optional/optional.hpp +85 -24
  876. data/src/cxx_supportlib/vendor-modified/boost/optional/optional_io.hpp +3 -2
  877. data/src/cxx_supportlib/vendor-modified/boost/pool/pool.hpp +22 -9
  878. data/src/cxx_supportlib/vendor-modified/boost/predef/architecture/loongarch.h +41 -0
  879. data/src/cxx_supportlib/vendor-modified/boost/predef/architecture/sparc.h +2 -2
  880. data/src/cxx_supportlib/vendor-modified/boost/predef/architecture.h +1 -0
  881. data/src/cxx_supportlib/vendor-modified/boost/predef/language/stdc.h +1 -1
  882. data/src/cxx_supportlib/vendor-modified/boost/predef/language/stdcpp.h +2 -2
  883. data/src/cxx_supportlib/vendor-modified/boost/predef/other/endian.h +1 -0
  884. data/src/cxx_supportlib/vendor-modified/boost/predef/version.h +1 -1
  885. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/basic_regex_parser.hpp +8 -1
  886. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/icu.hpp +1 -1
  887. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/pattern_except.hpp +3 -2
  888. data/src/cxx_supportlib/vendor-modified/boost/regex/v4/perl_matcher_non_recursive.hpp +1 -0
  889. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/basic_regex_creator.hpp +4 -3
  890. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/basic_regex_parser.hpp +23 -13
  891. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/icu.hpp +1 -1
  892. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/mem_block_cache.hpp +2 -0
  893. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/pattern_except.hpp +3 -2
  894. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/perl_matcher_common.hpp +6 -0
  895. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/perl_matcher_non_recursive.hpp +3 -1
  896. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/w32_regex_traits.hpp +235 -104
  897. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/shared_count.hpp +1 -1
  898. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +4 -2
  899. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_counted_impl.hpp +1 -1
  900. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_array.hpp +1 -1
  901. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/scoped_ptr.hpp +1 -1
  902. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_array.hpp +1 -1
  903. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/shared_ptr.hpp +3 -6
  904. data/src/cxx_supportlib/vendor-modified/boost/static_assert.hpp +2 -1
  905. data/src/cxx_supportlib/vendor-modified/boost/system/detail/append_int.hpp +32 -0
  906. data/src/cxx_supportlib/vendor-modified/boost/system/detail/config.hpp +18 -2
  907. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category.hpp +31 -7
  908. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_category_impl.hpp +78 -21
  909. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_code.hpp +211 -42
  910. data/src/cxx_supportlib/vendor-modified/boost/system/detail/error_condition.hpp +77 -19
  911. data/src/cxx_supportlib/vendor-modified/boost/system/detail/snprintf.hpp +3 -0
  912. data/src/cxx_supportlib/vendor-modified/boost/system/detail/std_category.hpp +9 -67
  913. data/src/cxx_supportlib/vendor-modified/boost/system/detail/std_category_impl.hpp +97 -0
  914. data/src/cxx_supportlib/vendor-modified/boost/system/detail/system_category_impl.hpp +5 -17
  915. data/src/cxx_supportlib/vendor-modified/boost/system/detail/system_category_message.hpp +71 -0
  916. data/src/cxx_supportlib/vendor-modified/boost/system/errc.hpp +7 -0
  917. data/src/cxx_supportlib/vendor-modified/boost/system/system_error.hpp +30 -59
  918. data/src/cxx_supportlib/vendor-modified/boost/thread/pthread/thread_data.hpp +1 -1
  919. data/src/cxx_supportlib/vendor-modified/boost/thread/scoped_thread.hpp +9 -0
  920. data/src/cxx_supportlib/vendor-modified/boost/thread/thread_guard.hpp +5 -0
  921. data/src/cxx_supportlib/vendor-modified/boost/throw_exception.hpp +103 -5
  922. data/src/cxx_supportlib/vendor-modified/boost/token_functions.hpp +2 -2
  923. data/src/cxx_supportlib/vendor-modified/boost/tuple/detail/tuple_basic.hpp +22 -21
  924. data/src/cxx_supportlib/vendor-modified/boost/type_index/stl_type_index.hpp +1 -1
  925. data/src/cxx_supportlib/vendor-modified/boost/type_index/type_index_facade.hpp +1 -1
  926. data/src/cxx_supportlib/vendor-modified/boost/type_index.hpp +1 -1
  927. data/src/cxx_supportlib/vendor-modified/boost/type_traits/detail/config.hpp +4 -1
  928. data/src/cxx_supportlib/vendor-modified/boost/type_traits/intrinsics.hpp +1 -1
  929. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_complete.hpp +2 -1
  930. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_function.hpp +1 -1
  931. data/src/cxx_supportlib/vendor-modified/boost/type_traits/is_member_function_pointer.hpp +1 -1
  932. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fca.hpp +819 -0
  933. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/fwd.hpp +2 -1
  934. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/implementation.hpp +1647 -2909
  935. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/map.hpp +8 -14
  936. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/prime_fmod.hpp +262 -0
  937. data/src/cxx_supportlib/vendor-modified/boost/unordered/detail/set.hpp +8 -13
  938. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map.hpp +301 -142
  939. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_map_fwd.hpp +10 -1
  940. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set.hpp +199 -76
  941. data/src/cxx_supportlib/vendor-modified/boost/unordered/unordered_set_fwd.hpp +10 -1
  942. data/src/cxx_supportlib/vendor-modified/boost/utility/base_from_member.hpp +2 -1
  943. data/src/cxx_supportlib/vendor-modified/boost/utility/binary.hpp +3 -2
  944. data/src/cxx_supportlib/vendor-modified/boost/utility/in_place_factory.hpp +6 -0
  945. data/src/cxx_supportlib/vendor-modified/boost/utility/result_of.hpp +13 -2
  946. data/src/cxx_supportlib/vendor-modified/boost/utility/string_ref.hpp +6 -2
  947. data/src/cxx_supportlib/vendor-modified/boost/utility/string_view.hpp +24 -3
  948. data/src/cxx_supportlib/vendor-modified/boost/utility/typed_in_place_factory.hpp +6 -1
  949. data/src/cxx_supportlib/vendor-modified/boost/utility/value_init.hpp +5 -1
  950. data/src/cxx_supportlib/vendor-modified/boost/version.hpp +2 -2
  951. data/src/ruby_supportlib/phusion_passenger/packaging.rb +1 -0
  952. data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +3 -2
  953. data/src/ruby_supportlib/phusion_passenger/platform_info/binary_compatibility.rb +1 -1
  954. data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +1 -1
  955. data/src/ruby_supportlib/phusion_passenger/platform_info/operating_system.rb +4 -4
  956. data/src/ruby_supportlib/phusion_passenger/platform_info/ruby.rb +2 -2
  957. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +9 -0
  958. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  959. metadata +129 -14
  960. data/src/cxx_supportlib/vendor-modified/boost/asio/detail/reactor_fwd.hpp +0 -42
  961. data/src/cxx_supportlib/vendor-modified/boost/checked_delete.hpp +0 -17
  962. data/src/cxx_supportlib/vendor-modified/boost/pointer_to_other.hpp +0 -55
  963. data/src/cxx_supportlib/vendor-modified/boost/regex/v5/indexed_bit_flag.hpp +0 -54
  964. data/src/cxx_supportlib/vendor-modified/boost/smart_ptr/detail/sp_obsolete.hpp +0 -32
@@ -1,6 +1,7 @@
1
1
  /////////////////////////////////////////////////////////////////////////////
2
2
  //
3
- // (C) Copyright Ion Gaztanaga 2006-2015
3
+ // (C) Copyright Ion Gaztanaga 2006-2022
4
+ // (C) Copyright 2022 Joaquin M Lopez Munoz.
4
5
  //
5
6
  // Distributed under the Boost Software License, Version 1.0.
6
7
  // (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +10,21 @@
9
10
  // See http://www.boost.org/libs/intrusive for documentation.
10
11
  //
11
12
  /////////////////////////////////////////////////////////////////////////////
13
+
14
+ // fastmod_buckets option is implemented reusing parts of Joaquin M. Lopez
15
+ // Munoz's "fxa_unordered" library (proof of concept of closed- and
16
+ // open-addressing unordered associative containers), released under
17
+ // Boost Software License:
18
+ //
19
+ // https://github.com/joaquintides/fxa_unordered/
20
+ //
21
+ // On cases and systems that can't take advantage of Daniel Lemire's
22
+ // "fastmod" (https://github.com/lemire/fastmod) approach,
23
+ // precomputed divisions are used.
24
+ //
25
+ // As always, thanks Joaquin for your great work!
26
+
27
+
12
28
  #ifndef BOOST_INTRUSIVE_HASHTABLE_HPP
13
29
  #define BOOST_INTRUSIVE_HASHTABLE_HPP
14
30
 
@@ -27,12 +43,17 @@
27
43
  #include <boost/intrusive/detail/simple_disposers.hpp>
28
44
  #include <boost/intrusive/detail/size_holder.hpp>
29
45
  #include <boost/intrusive/detail/iterator.hpp>
46
+ #include <boost/intrusive/detail/get_value_traits.hpp>
47
+ #include <boost/intrusive/detail/algorithm.hpp>
48
+ #include <boost/intrusive/detail/value_functors.hpp>
30
49
 
31
50
  //Implementation utilities
32
51
  #include <boost/intrusive/unordered_set_hook.hpp>
33
- #include <boost/intrusive/slist.hpp>
52
+ #include <boost/intrusive/detail/slist_iterator.hpp>
34
53
  #include <boost/intrusive/pointer_traits.hpp>
35
54
  #include <boost/intrusive/detail/mpl.hpp>
55
+ #include <boost/intrusive/circular_slist_algorithms.hpp>
56
+ #include <boost/intrusive/linear_slist_algorithms.hpp>
36
57
 
37
58
  //boost
38
59
  #include <boost/container_hash/hash.hpp>
@@ -40,28 +61,305 @@
40
61
  #include <boost/static_assert.hpp>
41
62
  #include <boost/move/utility_core.hpp>
42
63
  #include <boost/move/adl_move_swap.hpp>
64
+ #include <boost/move/algo/detail/search.hpp>
43
65
 
44
66
  //std C++
45
- #include <boost/intrusive/detail/minimal_less_equal_header.hpp> //std::equal_to
46
67
  #include <boost/intrusive/detail/minimal_pair_header.hpp> //std::pair
47
- #include <algorithm> //std::lower_bound, std::upper_bound
48
68
  #include <cstddef> //std::size_t
69
+ #include <boost/cstdint.hpp> //std::uint64_t
49
70
 
50
71
  #if defined(BOOST_HAS_PRAGMA_ONCE)
51
72
  # pragma once
52
73
  #endif
53
74
 
75
+ #ifdef _MSC_VER
76
+ #include <intrin.h>
77
+ #endif
78
+
79
+
54
80
  namespace boost {
55
81
  namespace intrusive {
56
82
 
83
+ #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
84
+
57
85
  /// @cond
58
86
 
87
+ #if !defined(BOOST_NO_INT64_T)&&\
88
+ (defined(BOOST_HAS_INT128) || (defined(_MSC_VER) && defined(_WIN64)))
89
+ #define BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT
90
+ #endif
91
+
92
+ //We only support LLP64(Win64) or LP64(most Unix) data models
93
+ #ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long)
94
+ # define BOOST_INTRUSIVE_SIZE_C(NUMBER) NUMBER##ULL
95
+ # define BOOST_INTRUSIVE_64_BIT_SIZE_T 1
96
+ #else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long)
97
+ # define BOOST_INTRUSIVE_SIZE_C(NUMBER) NUMBER##UL
98
+ # define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0)
99
+ #endif
100
+
101
+
102
+ template<int Dummy = 0>
103
+ struct prime_list_holder
104
+ {
105
+ private:
106
+
107
+ template <class SizeType> // sizeof(SizeType) < sizeof(std::size_t)
108
+ static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::true_)
109
+ { return n < std::size_t(SizeType(-1)) ? static_cast<SizeType>(n) : SizeType(-1); }
110
+
111
+ template <class SizeType> // sizeof(SizeType) == sizeof(std::size_t)
112
+ static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::false_)
113
+ { return static_cast<SizeType>(n); }
114
+
115
+ static const std::size_t prime_list[];
116
+ static const std::size_t prime_list_size;
117
+
118
+ static const std::size_t *suggested_lower_bucket_count_ptr(std::size_t n)
119
+ {
120
+ const std::size_t *primes = &prime_list[0];
121
+ const std::size_t *primes_end = primes + prime_list_size;
122
+ std::size_t const* bound =
123
+ boost::movelib::lower_bound(primes, primes_end, n, value_less<std::size_t>());
124
+ bound -= std::size_t(bound == primes_end);
125
+ return bound;
126
+ }
127
+
128
+ static const std::size_t *suggested_upper_bucket_count_ptr(std::size_t n)
129
+ {
130
+ const std::size_t *primes = &prime_list[0];
131
+ const std::size_t *primes_end = primes + prime_list_size;
132
+ std::size_t const* bound =
133
+ boost::movelib::upper_bound(primes, primes_end, n, value_less<std::size_t>());
134
+ bound -= std::size_t(bound == primes_end);
135
+ return bound;
136
+ }
137
+
138
+ static std::size_t suggested_lower_bucket_count_impl(std::size_t n)
139
+ { return *suggested_lower_bucket_count_ptr(n); }
140
+
141
+ static std::size_t suggested_upper_bucket_count_impl(std::size_t n)
142
+ { return *suggested_upper_bucket_count_ptr(n); }
143
+
144
+ public:
145
+
146
+ template <class SizeType>
147
+ static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count(SizeType n)
148
+ {
149
+ std::size_t const c = suggested_upper_bucket_count_impl(static_cast<std::size_t>(n));
150
+ return truncate_size_type<SizeType>(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>());
151
+ }
152
+
153
+ template <class SizeType>
154
+ static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count(SizeType n)
155
+ {
156
+ std::size_t const c = suggested_lower_bucket_count_impl(static_cast<std::size_t>(n));
157
+ return truncate_size_type<SizeType>(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>());
158
+ }
159
+
160
+ static BOOST_INTRUSIVE_FORCEINLINE std::size_t suggested_lower_bucket_count_idx(std::size_t n)
161
+ { return static_cast<std::size_t>(suggested_lower_bucket_count_ptr(n) - &prime_list[0]); }
162
+
163
+ static BOOST_INTRUSIVE_FORCEINLINE std::size_t suggested_upper_bucket_count_idx(std::size_t n)
164
+ { return static_cast<std::size_t>(suggested_upper_bucket_count_ptr(n) - &prime_list[0]); }
165
+
166
+ static BOOST_INTRUSIVE_FORCEINLINE std::size_t size_from_index(std::size_t n)
167
+ { return prime_list[std::ptrdiff_t(n)]; }
168
+
169
+ template<std::size_t SizeIndex>
170
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t modfunc(std::size_t hash) { return hash % prime_list[SizeIndex]; }
171
+
172
+ static std::size_t(*const positions[])(std::size_t);
173
+
174
+ #if defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
175
+ static const uint64_t inv_sizes32[];
176
+ static const std::size_t inv_sizes32_size;
177
+ #endif
178
+
179
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t lower_size_index(std::size_t n)
180
+ { return prime_list_holder<>::suggested_lower_bucket_count_idx(n); }
181
+
182
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t upper_size_index(std::size_t n)
183
+ { return prime_list_holder<>::suggested_upper_bucket_count_idx(n); }
184
+
185
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t size(std::size_t size_index)
186
+ { return prime_list_holder<>::size_from_index(size_index); }
187
+
188
+ #if defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
189
+ // https://github.com/lemire/fastmod
190
+
191
+
192
+ BOOST_INTRUSIVE_FORCEINLINE static uint64_t mul128_u32(uint64_t lowbits, uint32_t d)
193
+ {
194
+ #if defined(_MSC_VER)
195
+ return __umulh(lowbits, d);
196
+ #else
197
+ __extension__ typedef unsigned __int128 ext_uint128_t;
198
+ return (ext_uint128_t(lowbits) * d) >> 64;
199
+ #endif
200
+ }
201
+
202
+ BOOST_INTRUSIVE_FORCEINLINE static uint32_t fastmod_u32(uint32_t a, uint64_t M, uint32_t d)
203
+ {
204
+ uint64_t lowbits = M * a;
205
+ return (uint32_t)(mul128_u32(lowbits, d));
206
+ }
207
+ #endif // defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
208
+
209
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t position(std::size_t hash,std::size_t size_index)
210
+ {
211
+ #if defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT) && BOOST_INTRUSIVE_64_BIT_SIZE_T
212
+ const std::size_t sizes_under_32bit = sizeof(inv_sizes32)/sizeof(inv_sizes32[0]);
213
+ if(BOOST_LIKELY(size_index < sizes_under_32bit)){
214
+ return fastmod_u32( uint32_t(hash)+uint32_t(hash>>32)
215
+ , inv_sizes32[size_index]
216
+ , uint32_t(prime_list[size_index]) );
217
+ }
218
+ else{
219
+ return positions[size_index-sizes_under_32bit](hash);
220
+ }
221
+ #elif defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
222
+ return fastmod_u32(hash, inv_sizes32[size_index], uint32_t(sizes[size_index]));
223
+ #else
224
+ return positions[size_index](hash);
225
+ #endif // defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
226
+ }
227
+ };
228
+
229
+ template<int Dummy>
230
+ std::size_t(* const prime_list_holder<Dummy>::positions[])(std::size_t) =
231
+ {
232
+ #if !defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
233
+ modfunc< 0>,modfunc< 1>,modfunc< 2>,modfunc< 3>,modfunc< 4>,
234
+ modfunc< 5>,modfunc< 6>,modfunc< 7>,modfunc< 8>,modfunc< 9>,
235
+ modfunc<10>,modfunc<11>,modfunc<12>,modfunc<13>,modfunc<14>,
236
+ modfunc<15>,modfunc<16>,modfunc<17>,modfunc<18>,modfunc<19>,
237
+ modfunc<20>,modfunc<21>,modfunc<22>,modfunc<23>,modfunc<24>,
238
+ modfunc<25>,modfunc<26>,modfunc<27>,modfunc<28>,modfunc<29>,
239
+ modfunc<30>,
240
+ #endif
241
+ # if BOOST_INTRUSIVE_64_BIT_SIZE_T
242
+ modfunc<31>,modfunc<32>,modfunc<33>,modfunc<34>,
243
+ modfunc<35>,modfunc<36>,modfunc<37>,modfunc<38>,modfunc<39>,
244
+ modfunc<40>,modfunc<41>,modfunc<42>,modfunc<43>,modfunc<44>,
245
+ modfunc<45>,modfunc<46>,modfunc<47>,modfunc<48>,modfunc<49>,
246
+ modfunc<50>,modfunc<51>,modfunc<52>,modfunc<53>,modfunc<54>,
247
+ modfunc<55>,modfunc<56>,modfunc<57>,modfunc<58>,modfunc<59>,
248
+ modfunc<60>,modfunc<61>,modfunc<62>,modfunc<63>
249
+ # else
250
+ modfunc<31>
251
+ # endif
252
+ };
253
+
254
+ template<int Dummy>
255
+ const std::size_t prime_list_holder<Dummy>::prime_list[] = {
256
+ BOOST_INTRUSIVE_SIZE_C(3), BOOST_INTRUSIVE_SIZE_C(7),
257
+ BOOST_INTRUSIVE_SIZE_C(11), BOOST_INTRUSIVE_SIZE_C(17),
258
+ BOOST_INTRUSIVE_SIZE_C(29), BOOST_INTRUSIVE_SIZE_C(53),
259
+ BOOST_INTRUSIVE_SIZE_C(97), BOOST_INTRUSIVE_SIZE_C(193),
260
+ BOOST_INTRUSIVE_SIZE_C(389), BOOST_INTRUSIVE_SIZE_C(769),
261
+ BOOST_INTRUSIVE_SIZE_C(1543), BOOST_INTRUSIVE_SIZE_C(3079),
262
+ BOOST_INTRUSIVE_SIZE_C(6151), BOOST_INTRUSIVE_SIZE_C(12289),
263
+ BOOST_INTRUSIVE_SIZE_C(24593), BOOST_INTRUSIVE_SIZE_C(49157),
264
+ BOOST_INTRUSIVE_SIZE_C(98317), BOOST_INTRUSIVE_SIZE_C(196613),
265
+ BOOST_INTRUSIVE_SIZE_C(393241), BOOST_INTRUSIVE_SIZE_C(786433),
266
+ BOOST_INTRUSIVE_SIZE_C(1572869), BOOST_INTRUSIVE_SIZE_C(3145739),
267
+ BOOST_INTRUSIVE_SIZE_C(6291469), BOOST_INTRUSIVE_SIZE_C(12582917),
268
+ BOOST_INTRUSIVE_SIZE_C(25165843), BOOST_INTRUSIVE_SIZE_C(50331653),
269
+ BOOST_INTRUSIVE_SIZE_C(100663319), BOOST_INTRUSIVE_SIZE_C(201326611),
270
+ BOOST_INTRUSIVE_SIZE_C(402653189), BOOST_INTRUSIVE_SIZE_C(805306457),
271
+ BOOST_INTRUSIVE_SIZE_C(1610612741), //0-30 indexes
272
+ #if BOOST_INTRUSIVE_64_BIT_SIZE_T
273
+ //Taken from Boost.MultiIndex code, thanks to Joaquin M. Lopez Munoz.
274
+ BOOST_INTRUSIVE_SIZE_C(3221225473), //<- 32 bit values stop here (index 31)
275
+ BOOST_INTRUSIVE_SIZE_C(6442450939), BOOST_INTRUSIVE_SIZE_C(12884901893),
276
+ BOOST_INTRUSIVE_SIZE_C(25769803751), BOOST_INTRUSIVE_SIZE_C(51539607551),
277
+ BOOST_INTRUSIVE_SIZE_C(103079215111), BOOST_INTRUSIVE_SIZE_C(206158430209),
278
+ BOOST_INTRUSIVE_SIZE_C(412316860441), BOOST_INTRUSIVE_SIZE_C(824633720831),
279
+ BOOST_INTRUSIVE_SIZE_C(1649267441651), BOOST_INTRUSIVE_SIZE_C(3298534883309),
280
+ BOOST_INTRUSIVE_SIZE_C(6597069766657), BOOST_INTRUSIVE_SIZE_C(13194139533299),
281
+ BOOST_INTRUSIVE_SIZE_C(26388279066623), BOOST_INTRUSIVE_SIZE_C(52776558133303),
282
+ BOOST_INTRUSIVE_SIZE_C(105553116266489), BOOST_INTRUSIVE_SIZE_C(211106232532969),
283
+ BOOST_INTRUSIVE_SIZE_C(422212465066001), BOOST_INTRUSIVE_SIZE_C(844424930131963),
284
+ BOOST_INTRUSIVE_SIZE_C(1688849860263953), BOOST_INTRUSIVE_SIZE_C(3377699720527861),
285
+ BOOST_INTRUSIVE_SIZE_C(6755399441055731), BOOST_INTRUSIVE_SIZE_C(13510798882111483),
286
+ BOOST_INTRUSIVE_SIZE_C(27021597764222939), BOOST_INTRUSIVE_SIZE_C(54043195528445957),
287
+ BOOST_INTRUSIVE_SIZE_C(108086391056891903), BOOST_INTRUSIVE_SIZE_C(216172782113783843),
288
+ BOOST_INTRUSIVE_SIZE_C(432345564227567621), BOOST_INTRUSIVE_SIZE_C(864691128455135207),
289
+ BOOST_INTRUSIVE_SIZE_C(1729382256910270481), BOOST_INTRUSIVE_SIZE_C(3458764513820540933),
290
+ BOOST_INTRUSIVE_SIZE_C(6917529027641081903), BOOST_INTRUSIVE_SIZE_C(9223372036854775783) //(index 63)
291
+ #else
292
+ BOOST_INTRUSIVE_SIZE_C(2147483647) //<- 32 bit stops here (index 31) as ptrdiff_t is signed
293
+ #endif
294
+ };
295
+
296
+ template<int Dummy>
297
+ const std::size_t prime_list_holder<Dummy>::prime_list_size
298
+ = sizeof(prime_list) / sizeof(std::size_t);
299
+
300
+
301
+ #if defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
302
+
303
+ template<int Dummy>
304
+ const uint64_t prime_list_holder<Dummy>::inv_sizes32[] = {
305
+ BOOST_INTRUSIVE_SIZE_C(6148914691236517206), //3
306
+ BOOST_INTRUSIVE_SIZE_C(2635249153387078803), //7
307
+ BOOST_INTRUSIVE_SIZE_C(1676976733973595602), //11
308
+ BOOST_INTRUSIVE_SIZE_C(1085102592571150096), //17
309
+ BOOST_INTRUSIVE_SIZE_C(636094623231363849), //29
310
+ BOOST_INTRUSIVE_SIZE_C(348051774975651918), //53
311
+ BOOST_INTRUSIVE_SIZE_C(190172619316593316), //97
312
+ BOOST_INTRUSIVE_SIZE_C(95578984837873325), //193
313
+ BOOST_INTRUSIVE_SIZE_C(47420935922132524), //389
314
+ BOOST_INTRUSIVE_SIZE_C(23987963684927896), //769
315
+ BOOST_INTRUSIVE_SIZE_C(11955116055547344), //1543
316
+ BOOST_INTRUSIVE_SIZE_C(5991147799191151), //3079
317
+ BOOST_INTRUSIVE_SIZE_C(2998982941588287), //6151
318
+ BOOST_INTRUSIVE_SIZE_C(1501077717772769), //12289
319
+ BOOST_INTRUSIVE_SIZE_C(750081082979285), //24593
320
+ BOOST_INTRUSIVE_SIZE_C(375261795343686), //49157
321
+ BOOST_INTRUSIVE_SIZE_C(187625172388393), //98317
322
+ BOOST_INTRUSIVE_SIZE_C(93822606204624), //196613
323
+ BOOST_INTRUSIVE_SIZE_C(46909513691883), //393241
324
+ BOOST_INTRUSIVE_SIZE_C(23456218233098), //786433
325
+ BOOST_INTRUSIVE_SIZE_C(11728086747027), //1572869
326
+ BOOST_INTRUSIVE_SIZE_C(5864041509391), //3145739
327
+ BOOST_INTRUSIVE_SIZE_C(2932024948977), //6291469
328
+ BOOST_INTRUSIVE_SIZE_C(1466014921160), //12582917
329
+ BOOST_INTRUSIVE_SIZE_C(733007198436), //25165843
330
+ BOOST_INTRUSIVE_SIZE_C(366503839517), //50331653
331
+ BOOST_INTRUSIVE_SIZE_C(183251896093), //100663319
332
+ BOOST_INTRUSIVE_SIZE_C(91625960335), //201326611
333
+ BOOST_INTRUSIVE_SIZE_C(45812983922), //402653189
334
+ BOOST_INTRUSIVE_SIZE_C(22906489714), //805306457
335
+ BOOST_INTRUSIVE_SIZE_C(11453246088), //1610612741
336
+ BOOST_INTRUSIVE_SIZE_C(5726623060) //3221225473
337
+ };
338
+
339
+ template<int Dummy>
340
+ const std::size_t prime_list_holder<Dummy>::inv_sizes32_size
341
+ = sizeof(inv_sizes32) / sizeof(uint64_t);
342
+
343
+ #endif // defined(BOOST_INTRUSIVE_FCA_FASTMOD_SUPPORT)
344
+
345
+ struct prime_fmod_size : prime_list_holder<>
346
+ {
347
+ };
348
+
349
+
350
+ #undef BOOST_INTRUSIVE_SIZE_C
351
+ #undef BOOST_INTRUSIVE_64_BIT_SIZE_T
352
+
353
+ #endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
354
+
355
+
356
+
59
357
  template<class InputIt, class T>
60
358
  InputIt priv_algo_find(InputIt first, InputIt last, const T& value)
61
359
  {
62
360
  for (; first != last; ++first) {
63
361
  if (*first == value) {
64
- return first;
362
+ return first;
65
363
  }
66
364
  }
67
365
  return last;
@@ -105,234 +403,173 @@ bool priv_algo_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, F
105
403
  continue; //We've seen this one before.
106
404
  }
107
405
  distance_type matches = (priv_algo_count)(first2, last2, *scan);
108
- if (0 == matches || (priv_algo_count)(scan, last1, *scan != matches)){
406
+ if (0 == matches || (priv_algo_count)(scan, last1, *scan) != matches){
109
407
  return false;
110
408
  }
111
409
  }
112
410
  return true;
113
411
  }
114
412
 
115
- template<int Dummy = 0>
116
- struct prime_list_holder
413
+ struct hash_bool_flags
117
414
  {
118
- private:
119
-
120
- template <class SizeType> // sizeof(SizeType) < sizeof(std::size_t)
121
- static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::true_)
122
- {
123
- return n < std::size_t(SizeType(-1)) ? static_cast<SizeType>(n) : SizeType(-1);
124
- }
415
+ static const std::size_t unique_keys_pos = 1u;
416
+ static const std::size_t constant_time_size_pos = 2u;
417
+ static const std::size_t power_2_buckets_pos = 4u;
418
+ static const std::size_t cache_begin_pos = 8u;
419
+ static const std::size_t compare_hash_pos = 16u;
420
+ static const std::size_t incremental_pos = 32u;
421
+ static const std::size_t linear_buckets_pos = 64u;
422
+ static const std::size_t fastmod_buckets_pos = 128u;
423
+ };
125
424
 
126
- template <class SizeType> // sizeof(SizeType) == sizeof(std::size_t)
127
- static BOOST_INTRUSIVE_FORCEINLINE SizeType truncate_size_type(std::size_t n, detail::false_)
128
- {
129
- return static_cast<SizeType>(n);
130
- }
425
+ template<class Bucket, class Algo, class Disposer, class SizeType>
426
+ class exception_bucket_disposer
427
+ {
428
+ Bucket *cont_;
429
+ Disposer &disp_;
430
+ const SizeType &constructed_;
131
431
 
132
- template <class SizeType> //sizeof(SizeType) > sizeof(std::size_t)
133
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count_dispatch(SizeType n, detail::true_)
134
- {
135
- std::size_t const c = n > std::size_t(-1)
136
- ? std::size_t(-1)
137
- : suggested_upper_bucket_count_impl(static_cast<std::size_t>(n));
138
- return static_cast<SizeType>(c);
139
- }
432
+ exception_bucket_disposer(const exception_bucket_disposer&);
433
+ exception_bucket_disposer &operator=(const exception_bucket_disposer&);
140
434
 
141
- template <class SizeType> //sizeof(SizeType) > sizeof(std::size_t)
142
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count_dispatch(SizeType n, detail::true_)
143
- {
144
- std::size_t const c = n > std::size_t(-1)
145
- ? std::size_t(-1)
146
- : suggested_lower_bucket_count_impl(static_cast<std::size_t>(n));
147
- return static_cast<SizeType>(c);
148
- }
435
+ public:
149
436
 
150
- template <class SizeType>
151
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count_dispatch(SizeType n, detail::false_)
152
- {
153
- std::size_t const c = suggested_upper_bucket_count_impl(static_cast<std::size_t>(n));
154
- return truncate_size_type<SizeType>(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>());
437
+ exception_bucket_disposer
438
+ (Bucket &cont, Disposer &disp, const SizeType &constructed)
439
+ : cont_(&cont), disp_(disp), constructed_(constructed)
440
+ {}
155
441
 
156
- }
442
+ BOOST_INTRUSIVE_FORCEINLINE void release()
443
+ { cont_ = 0; }
157
444
 
158
- template <class SizeType>
159
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count_dispatch(SizeType n, detail::false_)
445
+ ~exception_bucket_disposer()
160
446
  {
161
- std::size_t const c = suggested_lower_bucket_count_impl(static_cast<std::size_t>(n));
162
- return truncate_size_type<SizeType>(c, detail::bool_<(sizeof(SizeType) < sizeof(std::size_t))>());
447
+ SizeType n = constructed_;
448
+ if(cont_){
449
+ while(n--){
450
+ Algo::detach_and_dispose(cont_[n].get_node_ptr(), disp_);
451
+ }
452
+ }
163
453
  }
454
+ };
164
455
 
165
- static const std::size_t prime_list[];
166
- static const std::size_t prime_list_size;
456
+ template<class SupposedValueTraits>
457
+ struct unordered_bucket_impl
458
+ {
459
+ typedef typename detail::get_node_traits
460
+ <SupposedValueTraits>::type node_traits;
461
+ typedef typename reduced_slist_node_traits
462
+ <node_traits>::type reduced_node_traits;
463
+ typedef bucket_impl<reduced_node_traits> type;
167
464
 
168
- static std::size_t suggested_lower_bucket_count_impl(std::size_t n)
169
- {
170
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
171
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
172
- std::size_t const* bound = std::lower_bound(primes, primes_end, n);
173
- //Tables have upper SIZE_MAX, so we must always found an entry
174
- BOOST_INTRUSIVE_INVARIANT_ASSERT(bound != primes_end);
175
- bound -= std::size_t(bound != primes);
176
- return *bound;
177
- }
465
+ typedef typename pointer_traits
466
+ <typename reduced_node_traits::node_ptr>
467
+ ::template rebind_pointer<type>::type pointer;
468
+ };
178
469
 
179
- static std::size_t suggested_upper_bucket_count_impl(std::size_t n)
180
- {
181
- const std::size_t *primes = &prime_list_holder<0>::prime_list[0];
182
- const std::size_t *primes_end = primes + prime_list_holder<0>::prime_list_size;
183
- std::size_t const* bound = std::upper_bound(primes, primes_end, n);
184
- bound -= std::size_t(bound == primes_end);
185
- return *bound;
186
- }
470
+ template<class SupposedValueTraits>
471
+ struct unordered_bucket_ptr_impl
472
+ {
473
+ typedef typename unordered_bucket_impl<SupposedValueTraits>::pointer type;
474
+ };
187
475
 
188
- public:
189
476
 
190
- template <class SizeType>
191
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_upper_bucket_count(SizeType n)
192
- {
193
- return (suggested_upper_bucket_count_dispatch)(n, detail::bool_<(sizeof(SizeType) > sizeof(std::size_t))>());
194
- }
477
+ template <class BucketPtr, class SizeType>
478
+ struct bucket_traits_impl
479
+ {
480
+ private:
481
+ BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl)
195
482
 
196
- template <class SizeType>
197
- static BOOST_INTRUSIVE_FORCEINLINE SizeType suggested_lower_bucket_count(SizeType n)
198
- {
199
- return (suggested_lower_bucket_count_dispatch)(n, detail::bool_<(sizeof(SizeType) > sizeof(std::size_t))>());
200
- }
201
- };
483
+ public:
484
+ /// @cond
202
485
 
203
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
486
+ typedef BucketPtr bucket_ptr;
487
+ typedef SizeType size_type;
204
488
 
205
- //We only support LLP64(Win64) or LP64(most Unix) data models
206
- #ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long)
207
- #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##ULL
208
- #define BOOST_INTRUSIVE_64_BIT_SIZE_T 1
209
- #else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long)
210
- #define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##UL
211
- #define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0)
212
- #endif
489
+ /// @endcond
213
490
 
214
- template<int Dummy>
215
- const std::size_t prime_list_holder<Dummy>::prime_list[] = {
216
- BOOST_INTRUSIVE_PRIME_C(3), BOOST_INTRUSIVE_PRIME_C(7),
217
- BOOST_INTRUSIVE_PRIME_C(11), BOOST_INTRUSIVE_PRIME_C(17),
218
- BOOST_INTRUSIVE_PRIME_C(29), BOOST_INTRUSIVE_PRIME_C(53),
219
- BOOST_INTRUSIVE_PRIME_C(97), BOOST_INTRUSIVE_PRIME_C(193),
220
- BOOST_INTRUSIVE_PRIME_C(389), BOOST_INTRUSIVE_PRIME_C(769),
221
- BOOST_INTRUSIVE_PRIME_C(1543), BOOST_INTRUSIVE_PRIME_C(3079),
222
- BOOST_INTRUSIVE_PRIME_C(6151), BOOST_INTRUSIVE_PRIME_C(12289),
223
- BOOST_INTRUSIVE_PRIME_C(24593), BOOST_INTRUSIVE_PRIME_C(49157),
224
- BOOST_INTRUSIVE_PRIME_C(98317), BOOST_INTRUSIVE_PRIME_C(196613),
225
- BOOST_INTRUSIVE_PRIME_C(393241), BOOST_INTRUSIVE_PRIME_C(786433),
226
- BOOST_INTRUSIVE_PRIME_C(1572869), BOOST_INTRUSIVE_PRIME_C(3145739),
227
- BOOST_INTRUSIVE_PRIME_C(6291469), BOOST_INTRUSIVE_PRIME_C(12582917),
228
- BOOST_INTRUSIVE_PRIME_C(25165843), BOOST_INTRUSIVE_PRIME_C(50331653),
229
- BOOST_INTRUSIVE_PRIME_C(100663319), BOOST_INTRUSIVE_PRIME_C(201326611),
230
- BOOST_INTRUSIVE_PRIME_C(402653189), BOOST_INTRUSIVE_PRIME_C(805306457),
231
- BOOST_INTRUSIVE_PRIME_C(1610612741), BOOST_INTRUSIVE_PRIME_C(3221225473),
232
- #if BOOST_INTRUSIVE_64_BIT_SIZE_T
233
- //Taken from Boost.MultiIndex code, thanks to Joaquin M Lopez Munoz.
234
- BOOST_INTRUSIVE_PRIME_C(6442450939), BOOST_INTRUSIVE_PRIME_C(12884901893),
235
- BOOST_INTRUSIVE_PRIME_C(25769803751), BOOST_INTRUSIVE_PRIME_C(51539607551),
236
- BOOST_INTRUSIVE_PRIME_C(103079215111), BOOST_INTRUSIVE_PRIME_C(206158430209),
237
- BOOST_INTRUSIVE_PRIME_C(412316860441), BOOST_INTRUSIVE_PRIME_C(824633720831),
238
- BOOST_INTRUSIVE_PRIME_C(1649267441651), BOOST_INTRUSIVE_PRIME_C(3298534883309),
239
- BOOST_INTRUSIVE_PRIME_C(6597069766657), BOOST_INTRUSIVE_PRIME_C(13194139533299),
240
- BOOST_INTRUSIVE_PRIME_C(26388279066623), BOOST_INTRUSIVE_PRIME_C(52776558133303),
241
- BOOST_INTRUSIVE_PRIME_C(105553116266489), BOOST_INTRUSIVE_PRIME_C(211106232532969),
242
- BOOST_INTRUSIVE_PRIME_C(422212465066001), BOOST_INTRUSIVE_PRIME_C(844424930131963),
243
- BOOST_INTRUSIVE_PRIME_C(1688849860263953), BOOST_INTRUSIVE_PRIME_C(3377699720527861),
244
- BOOST_INTRUSIVE_PRIME_C(6755399441055731), BOOST_INTRUSIVE_PRIME_C(13510798882111483),
245
- BOOST_INTRUSIVE_PRIME_C(27021597764222939), BOOST_INTRUSIVE_PRIME_C(54043195528445957),
246
- BOOST_INTRUSIVE_PRIME_C(108086391056891903), BOOST_INTRUSIVE_PRIME_C(216172782113783843),
247
- BOOST_INTRUSIVE_PRIME_C(432345564227567621), BOOST_INTRUSIVE_PRIME_C(864691128455135207),
248
- BOOST_INTRUSIVE_PRIME_C(1729382256910270481), BOOST_INTRUSIVE_PRIME_C(3458764513820540933),
249
- BOOST_INTRUSIVE_PRIME_C(6917529027641081903), BOOST_INTRUSIVE_PRIME_C(13835058055282163729),
250
- BOOST_INTRUSIVE_PRIME_C(18446744073709551557), BOOST_INTRUSIVE_PRIME_C(18446744073709551615) //Upper limit, just in case
251
- #else
252
- BOOST_INTRUSIVE_PRIME_C(4294967291), BOOST_INTRUSIVE_PRIME_C(4294967295) //Upper limit, just in case
253
- #endif
254
- };
491
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(bucket_ptr buckets, size_type len)
492
+ : buckets_(buckets), buckets_len_(len)
493
+ {}
255
494
 
256
- #undef BOOST_INTRUSIVE_PRIME_C
257
- #undef BOOST_INTRUSIVE_64_BIT_SIZE_T
495
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(const bucket_traits_impl& x)
496
+ : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
497
+ {}
258
498
 
259
- #endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
499
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
500
+ : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
501
+ {
502
+ x.buckets_ = bucket_ptr(); x.buckets_len_ = 0u;
503
+ }
260
504
 
261
- template<int Dummy>
262
- const std::size_t prime_list_holder<Dummy>::prime_list_size
263
- = sizeof(prime_list)/sizeof(std::size_t);
505
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x)
506
+ {
507
+ buckets_ = x.buckets_; buckets_len_ = x.buckets_len_;
508
+ x.buckets_ = bucket_ptr(); x.buckets_len_ = 0u; return *this;
509
+ }
264
510
 
265
- struct hash_bool_flags
266
- {
267
- static const std::size_t unique_keys_pos = 1u;
268
- static const std::size_t constant_time_size_pos = 2u;
269
- static const std::size_t power_2_buckets_pos = 4u;
270
- static const std::size_t cache_begin_pos = 8u;
271
- static const std::size_t compare_hash_pos = 16u;
272
- static const std::size_t incremental_pos = 32u;
273
- };
511
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x)
512
+ {
513
+ buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this;
514
+ }
274
515
 
275
- namespace detail {
516
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_begin() const
517
+ {
518
+ return buckets_;
519
+ }
276
520
 
277
- template<class SupposedValueTraits>
278
- struct get_slist_impl_from_supposed_value_traits
279
- {
280
- typedef SupposedValueTraits value_traits;
281
- typedef typename detail::get_node_traits
282
- <value_traits>::type node_traits;
283
- typedef typename get_slist_impl
284
- <typename reduced_slist_node_traits
285
- <node_traits>::type
286
- >::type type;
287
- };
521
+ BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT
522
+ {
523
+ return buckets_len_;
524
+ }
288
525
 
289
- template<class SupposedValueTraits>
290
- struct unordered_bucket_impl
291
- {
292
- typedef typename
293
- get_slist_impl_from_supposed_value_traits
294
- <SupposedValueTraits>::type slist_impl;
295
- typedef bucket_impl<slist_impl> implementation_defined;
296
- typedef implementation_defined type;
526
+ private:
527
+ bucket_ptr buckets_;
528
+ size_type buckets_len_;
297
529
  };
298
530
 
299
- template<class SupposedValueTraits>
300
- struct unordered_bucket_ptr_impl
301
- {
302
- typedef typename detail::get_node_traits
303
- <SupposedValueTraits>::type::node_ptr node_ptr;
304
- typedef typename unordered_bucket_impl
305
- <SupposedValueTraits>::type bucket_type;
306
-
307
- typedef typename pointer_traits
308
- <node_ptr>::template rebind_pointer
309
- < bucket_type >::type implementation_defined;
310
- typedef implementation_defined type;
311
- };
312
531
 
313
532
  template <class T>
314
533
  struct store_hash_is_true
315
534
  {
316
535
  template<bool Add>
317
- struct two_or_three {yes_type _[2 + Add];};
318
- template <class U> static yes_type test(...);
536
+ struct two_or_three {detail::yes_type _[2u + (unsigned)Add];};
537
+ template <class U> static detail::yes_type test(...);
319
538
  template <class U> static two_or_three<U::store_hash> test (int);
320
- static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
539
+ static const bool value = sizeof(test<T>(0)) > sizeof(detail::yes_type)*2u;
321
540
  };
322
541
 
323
542
  template <class T>
324
543
  struct optimize_multikey_is_true
325
544
  {
326
545
  template<bool Add>
327
- struct two_or_three {yes_type _[2 + Add];};
328
- template <class U> static yes_type test(...);
546
+ struct two_or_three { detail::yes_type _[2u + (unsigned)Add];};
547
+ template <class U> static detail::yes_type test(...);
329
548
  template <class U> static two_or_three<U::optimize_multikey> test (int);
330
- static const bool value = sizeof(test<T>(0)) > sizeof(yes_type)*2;
549
+ static const bool value = sizeof(test<T>(0)) > sizeof(detail::yes_type)*2u;
331
550
  };
332
551
 
552
+ template<bool StoreHash>
333
553
  struct insert_commit_data_impl
334
554
  {
335
555
  std::size_t hash;
556
+ std::size_t bucket_idx;
557
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t get_hash() const
558
+ { return hash; }
559
+
560
+ BOOST_INTRUSIVE_FORCEINLINE void set_hash(std::size_t h)
561
+ { hash = h; }
562
+ };
563
+
564
+ template<>
565
+ struct insert_commit_data_impl<false>
566
+ {
567
+ std::size_t bucket_idx;
568
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t get_hash() const
569
+ { return 0U; }
570
+
571
+ BOOST_INTRUSIVE_FORCEINLINE void set_hash(std::size_t)
572
+ {}
336
573
  };
337
574
 
338
575
  template<class Node, class SlistNodePtr>
@@ -375,21 +612,22 @@ struct group_functions
375
612
  typedef circular_slist_algorithms<node_traits> node_algorithms;
376
613
 
377
614
  static slist_node_ptr get_bucket_before_begin
378
- (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p)
615
+ (slist_node_ptr bucket_beg, slist_node_ptr bucket_last, slist_node_ptr sp, detail::true_)
379
616
  {
380
617
  //First find the last node of p's group.
381
618
  //This requires checking the first node of the next group or
382
619
  //the bucket node.
620
+ node_ptr p = dcast_bucket_ptr<node>(sp);
383
621
  node_ptr prev_node = p;
384
622
  node_ptr nxt(node_traits::get_next(p));
385
- while(!(bucket_beg <= nxt && nxt <= bucket_end) &&
623
+ while(!(bucket_beg <= nxt && nxt <= bucket_last) &&
386
624
  (group_traits::get_next(nxt) == prev_node)){
387
625
  prev_node = nxt;
388
626
  nxt = node_traits::get_next(nxt);
389
627
  }
390
628
 
391
629
  //If we've reached the bucket node just return it.
392
- if(bucket_beg <= nxt && nxt <= bucket_end){
630
+ if(bucket_beg <= nxt && nxt <= bucket_last){
393
631
  return nxt;
394
632
  }
395
633
 
@@ -398,17 +636,28 @@ struct group_functions
398
636
  node_ptr last_node_group = group_traits::get_next(first_node_of_group);
399
637
  slist_node_ptr possible_end = node_traits::get_next(last_node_group);
400
638
 
401
- while(!(bucket_beg <= possible_end && possible_end <= bucket_end)){
402
- first_node_of_group = detail::dcast_bucket_ptr<node>(possible_end);
639
+ while(!(bucket_beg <= possible_end && possible_end <= bucket_last)){
640
+ first_node_of_group = dcast_bucket_ptr<node>(possible_end);
403
641
  last_node_group = group_traits::get_next(first_node_of_group);
404
642
  possible_end = node_traits::get_next(last_node_group);
405
643
  }
406
644
  return possible_end;
407
645
  }
408
646
 
647
+ static slist_node_ptr get_bucket_before_begin
648
+ (slist_node_ptr bucket_beg, slist_node_ptr bucket_last, slist_node_ptr sp, detail::false_)
649
+ {
650
+ //The end node is embedded in the singly linked list:
651
+ //iterate until we reach it.
652
+ while (!(bucket_beg <= sp && sp <= bucket_last)){
653
+ sp = reduced_node_traits::get_next(sp);
654
+ }
655
+ return sp;
656
+ }
657
+
409
658
  static node_ptr get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group)
410
659
  {
411
- node_ptr nb = detail::dcast_bucket_ptr<node>(bucket_node);
660
+ node_ptr nb = dcast_bucket_ptr<node>(bucket_node);
412
661
  node_ptr n;
413
662
  while((n = node_traits::get_next(nb)) != first_in_group){
414
663
  nb = group_traits::get_next(n); //go to last in group
@@ -426,7 +675,7 @@ struct group_functions
426
675
  }
427
676
  }
428
677
 
429
- BOOST_INTRUSIVE_FORCEINLINE static void erase_from_group(const slist_node_ptr&, const node_ptr&, detail::false_)
678
+ BOOST_INTRUSIVE_FORCEINLINE static void erase_from_group(slist_node_ptr, node_ptr, detail::false_)
430
679
  {}
431
680
 
432
681
  BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_last_in_group(node_ptr first_in_group, detail::true_)
@@ -444,33 +693,35 @@ struct group_functions
444
693
  return n;
445
694
  }
446
695
 
447
- BOOST_INTRUSIVE_FORCEINLINE static node_ptr next_group_if_first_in_group(node_ptr ptr)
448
- {
449
- return node_traits::get_next(group_traits::get_next(ptr));
450
- }
451
-
452
696
  BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_first_in_group(node_ptr n, detail::false_)
453
697
  { return n; }
454
698
 
455
- BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr first_in_group, node_ptr n, true_)
699
+ BOOST_INTRUSIVE_FORCEINLINE static bool is_first_in_group(node_ptr ptr)
700
+ { return node_traits::get_next(group_traits::get_next(ptr)) != ptr; }
701
+
702
+
703
+ BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr first_in_group, node_ptr n, detail::true_)
456
704
  { group_algorithms::link_after(first_in_group, n); }
457
705
 
458
- static void insert_in_group(const node_ptr&, const node_ptr&, false_)
706
+ BOOST_INTRUSIVE_FORCEINLINE static void insert_in_group(node_ptr, node_ptr, detail::false_)
459
707
  {}
460
708
 
461
- BOOST_INTRUSIVE_FORCEINLINE static node_ptr split_group(node_ptr const new_first_in_group)
709
+ //Splits a group in two groups, and makes "new_first" the first node in the second group.
710
+ //Returns the first element of the first group
711
+ static node_ptr split_group(node_ptr const new_first)
462
712
  {
463
- node_ptr const first((get_first_in_group)(new_first_in_group, detail::true_()));
464
- if(first != new_first_in_group){
465
- node_ptr const last = group_traits::get_next(first);
466
- group_traits::set_next(first, group_traits::get_next(new_first_in_group));
467
- group_traits::set_next(new_first_in_group, last);
713
+ node_ptr const old_first((get_first_in_group)(new_first, detail::true_()));
714
+ //Check new_first was not the first in group
715
+ if(old_first != new_first){
716
+ node_ptr const last = group_traits::get_next(old_first);
717
+ group_traits::set_next(old_first, group_traits::get_next(new_first));
718
+ group_traits::set_next(new_first, last);
468
719
  }
469
- return first;
720
+ return old_first;
470
721
  }
471
722
  };
472
723
 
473
- template<class BucketType, class SplitTraits>
724
+ template<class BucketType, class SplitTraits, class SlistNodeAlgorithms>
474
725
  class incremental_rehash_rollback
475
726
  {
476
727
  private:
@@ -483,9 +734,9 @@ class incremental_rehash_rollback
483
734
 
484
735
  public:
485
736
  incremental_rehash_rollback
486
- (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_traits)
737
+ (bucket_type &source_bucket, bucket_type &destiny_bucket, split_traits &split_tr)
487
738
  : source_bucket_(source_bucket), destiny_bucket_(destiny_bucket)
488
- , split_traits_(split_traits), released_(false)
739
+ , split_traits_(split_tr), released_(false)
489
740
  {}
490
741
 
491
742
  BOOST_INTRUSIVE_FORCEINLINE void release()
@@ -496,7 +747,7 @@ class incremental_rehash_rollback
496
747
  if(!released_){
497
748
  //If an exception is thrown, just put all moved nodes back in the old bucket
498
749
  //and move back the split mark.
499
- destiny_bucket_.splice_after(destiny_bucket_.before_begin(), source_bucket_);
750
+ SlistNodeAlgorithms::transfer_after(destiny_bucket_.get_node_ptr(), source_bucket_.get_node_ptr());
500
751
  split_traits_.decrement();
501
752
  }
502
753
  }
@@ -511,10 +762,10 @@ class incremental_rehash_rollback
511
762
  template<class NodeTraits>
512
763
  struct node_functions
513
764
  {
514
- BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr p, std::size_t h, true_)
765
+ BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr p, std::size_t h, detail::true_)
515
766
  { return NodeTraits::set_hash(p, h); }
516
767
 
517
- BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr, std::size_t, false_)
768
+ BOOST_INTRUSIVE_FORCEINLINE static void store_hash(typename NodeTraits::node_ptr, std::size_t, detail::false_)
518
769
  {}
519
770
  };
520
771
 
@@ -524,26 +775,29 @@ BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket(std::size_t hash_value, s
524
775
  BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket(std::size_t hash_value, std::size_t bucket_cnt, detail::true_)
525
776
  { return hash_value & (bucket_cnt - 1); }
526
777
 
527
- template<bool Power2Buckets, bool Incremental>
528
- BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t bucket_cnt, std::size_t split)
778
+ template<bool Power2Buckets, bool Incremental> //!fastmod_buckets
779
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t bucket_cnt, std::size_t split, detail::false_)
529
780
  {
530
- std::size_t bucket_number = detail::hash_to_bucket(hash_value, bucket_cnt, detail::bool_<Power2Buckets>());
531
- if(Incremental)
781
+ std::size_t bucket_number = hash_to_bucket(hash_value, bucket_cnt, detail::bool_<Power2Buckets>());
782
+ BOOST_IF_CONSTEXPR(Incremental)
532
783
  bucket_number -= static_cast<std::size_t>(bucket_number >= split)*(bucket_cnt/2);
533
784
  return bucket_number;
534
785
  }
535
786
 
536
- } //namespace detail {
787
+ template<bool Power2Buckets, bool Incremental> //fastmod_buckets
788
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t hash_to_bucket_split(std::size_t hash_value, std::size_t bucket_cnt, std::size_t split, detail::true_)
789
+ {
790
+ return prime_fmod_size::position(hash_value, split); (void)bucket_cnt;
791
+ }
537
792
 
538
793
  //!This metafunction will obtain the type of a bucket
539
794
  //!from the value_traits or hook option to be used with
540
795
  //!a hash container.
541
796
  template<class ValueTraitsOrHookOption>
542
797
  struct unordered_bucket
543
- : public detail::unordered_bucket_impl
544
- <typename ValueTraitsOrHookOption::
545
- template pack<empty>::proto_value_traits
546
- >
798
+ : public unordered_bucket_impl
799
+ < typename ValueTraitsOrHookOption::
800
+ template pack<empty>::proto_value_traits>
547
801
  {};
548
802
 
549
803
  //!This metafunction will obtain the type of a bucket pointer
@@ -551,10 +805,9 @@ struct unordered_bucket
551
805
  //!a hash container.
552
806
  template<class ValueTraitsOrHookOption>
553
807
  struct unordered_bucket_ptr
554
- : public detail::unordered_bucket_ptr_impl
555
- <typename ValueTraitsOrHookOption::
556
- template pack<empty>::proto_value_traits
557
- >
808
+ : public unordered_bucket_ptr_impl
809
+ < typename ValueTraitsOrHookOption::
810
+ template pack<empty>::proto_value_traits>
558
811
  {};
559
812
 
560
813
  //!This metafunction will obtain the type of the default bucket traits
@@ -565,13 +818,12 @@ template<class ValueTraitsOrHookOption>
565
818
  struct unordered_default_bucket_traits
566
819
  {
567
820
  typedef typename ValueTraitsOrHookOption::
568
- template pack<empty>::proto_value_traits supposed_value_traits;
569
- typedef typename detail::
570
- get_slist_impl_from_supposed_value_traits
571
- <supposed_value_traits>::type slist_impl;
821
+ template pack<empty>::proto_value_traits supposed_value_traits;
822
+
572
823
  typedef bucket_traits_impl
573
- <slist_impl> implementation_defined;
574
- typedef implementation_defined type;
824
+ < typename unordered_bucket_ptr_impl
825
+ <supposed_value_traits>::type
826
+ , std::size_t> type;
575
827
  };
576
828
 
577
829
  struct default_bucket_traits;
@@ -597,30 +849,30 @@ struct hashtable_defaults
597
849
  static const bool cache_begin = false;
598
850
  static const bool compare_hash = false;
599
851
  static const bool incremental = false;
852
+ static const bool linear_buckets = false;
853
+ static const bool fastmod_buckets = false;
600
854
  };
601
855
 
602
856
  template<class ValueTraits, bool IsConst>
603
857
  struct downcast_node_to_value_t
604
858
  : public detail::node_to_value<ValueTraits, IsConst>
605
859
  {
606
- typedef detail::node_to_value<ValueTraits, IsConst> base_t;
607
- typedef typename base_t::result_type result_type;
608
- typedef ValueTraits value_traits;
609
- typedef typename get_slist_impl
610
- <typename reduced_slist_node_traits
611
- <typename value_traits::node_traits>::type
612
- >::type slist_impl;
860
+ typedef detail::node_to_value<ValueTraits, IsConst> base_t;
861
+ typedef typename base_t::result_type result_type;
862
+ typedef ValueTraits value_traits;
863
+ typedef typename unordered_bucket_impl
864
+ <value_traits>::type::node_traits::node node;
613
865
  typedef typename detail::add_const_if_c
614
- <typename slist_impl::node, IsConst>::type & first_argument_type;
866
+ <node, IsConst>::type &first_argument_type;
615
867
  typedef typename detail::add_const_if_c
616
868
  < typename ValueTraits::node_traits::node
617
- , IsConst>::type & intermediate_argument_type;
869
+ , IsConst>::type &intermediate_argument_type;
618
870
  typedef typename pointer_traits
619
871
  <typename ValueTraits::pointer>::
620
872
  template rebind_pointer
621
873
  <const ValueTraits>::type const_value_traits_ptr;
622
874
 
623
- BOOST_INTRUSIVE_FORCEINLINE downcast_node_to_value_t(const const_value_traits_ptr &ptr)
875
+ BOOST_INTRUSIVE_FORCEINLINE downcast_node_to_value_t(const_value_traits_ptr ptr)
624
876
  : base_t(ptr)
625
877
  {}
626
878
 
@@ -655,25 +907,58 @@ struct node_cast_adaptor
655
907
  //bucket_plus_vtraits stores ValueTraits + BucketTraits
656
908
  //this data is needed by iterators to obtain the
657
909
  //value from the iterator and detect the bucket
658
- template<class ValueTraits, class BucketTraits>
910
+ template<class ValueTraits, class BucketTraits, bool LinearBuckets>
659
911
  struct bucket_plus_vtraits
660
912
  {
913
+ private:
914
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_plus_vtraits)
915
+
916
+
917
+ struct data_type
918
+ : public ValueTraits, BucketTraits
919
+ {
920
+ private:
921
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(data_type)
922
+
923
+ public:
924
+ BOOST_INTRUSIVE_FORCEINLINE data_type(const ValueTraits& val_traits, const BucketTraits& b_traits)
925
+ : ValueTraits(val_traits), BucketTraits(b_traits)
926
+ {}
927
+
928
+ BOOST_INTRUSIVE_FORCEINLINE data_type(BOOST_RV_REF(data_type) other)
929
+ : ValueTraits (BOOST_MOVE_BASE(ValueTraits, other))
930
+ , BucketTraits(BOOST_MOVE_BASE(BucketTraits, other))
931
+ {}
932
+ } m_data;
933
+
934
+ public:
661
935
  typedef BucketTraits bucket_traits;
662
936
  typedef ValueTraits value_traits;
663
937
 
664
938
  static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
665
939
 
666
- typedef typename
667
- detail::get_slist_impl_from_supposed_value_traits
668
- <value_traits>::type slist_impl;
940
+ typedef typename unordered_bucket_impl
941
+ <value_traits>::type bucket_type;
942
+ typedef typename unordered_bucket_ptr_impl
943
+ <value_traits>::type bucket_ptr;
669
944
  typedef typename value_traits::node_traits node_traits;
945
+ typedef typename bucket_type::node_traits slist_node_traits;
670
946
  typedef unordered_group_adapter<node_traits> group_traits;
671
- typedef typename slist_impl::iterator siterator;
672
- typedef bucket_impl<slist_impl> bucket_type;
673
- typedef detail::group_functions<node_traits> group_functions_t;
674
- typedef typename slist_impl::node_algorithms node_algorithms;
675
- typedef typename slist_impl::node_ptr slist_node_ptr;
676
- typedef typename node_traits::node_ptr node_ptr;
947
+ typedef group_functions<node_traits> group_functions_t;
948
+ typedef typename detail::if_c
949
+ < LinearBuckets
950
+ , linear_slist_algorithms<slist_node_traits>
951
+ , circular_slist_algorithms<slist_node_traits>
952
+ >::type slist_node_algorithms;
953
+
954
+ typedef typename slist_node_traits::node_ptr slist_node_ptr;
955
+ typedef trivial_value_traits
956
+ <slist_node_traits, normal_link> slist_value_traits;
957
+ typedef slist_iterator<slist_value_traits, false> siterator;
958
+ typedef slist_iterator<slist_value_traits, true> const_siterator;
959
+
960
+ typedef typename node_traits::node_ptr node_ptr;
961
+ typedef typename node_traits::const_node_ptr const_node_ptr;
677
962
  typedef typename node_traits::node node;
678
963
  typedef typename value_traits::value_type value_type;
679
964
  typedef typename value_traits::pointer pointer;
@@ -690,16 +975,18 @@ struct bucket_plus_vtraits
690
975
  <typename value_traits::pointer>::
691
976
  template rebind_pointer
692
977
  <const bucket_plus_vtraits>::type const_bucket_value_traits_ptr;
693
- typedef typename detail::unordered_bucket_ptr_impl
694
- <value_traits>::type bucket_ptr;
978
+ typedef detail::bool_<LinearBuckets> linear_buckets_t;
979
+ typedef bucket_plus_vtraits& this_ref;
980
+
981
+ static const std::size_t bucket_overhead = LinearBuckets ? 1u : 0u;
695
982
 
696
- template<class BucketTraitsType>
697
- BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
698
- : data(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
983
+ BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(const ValueTraits &val_traits, const bucket_traits &b_traits)
984
+ : m_data(val_traits, b_traits)
699
985
  {}
700
986
 
701
- BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits & operator =(const bucket_plus_vtraits &x)
702
- { data.bucket_traits_ = x.data.bucket_traits_; return *this; }
987
+ BOOST_INTRUSIVE_FORCEINLINE bucket_plus_vtraits(BOOST_RV_REF(bucket_plus_vtraits) other)
988
+ : m_data(boost::move(((bucket_plus_vtraits&)other).m_data))
989
+ {}
703
990
 
704
991
  BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr priv_value_traits_ptr() const
705
992
  { return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
@@ -718,47 +1005,129 @@ struct bucket_plus_vtraits
718
1005
  //value traits
719
1006
  //
720
1007
  BOOST_INTRUSIVE_FORCEINLINE const value_traits &priv_value_traits() const
721
- { return this->data; }
1008
+ { return static_cast<const value_traits &>(this->m_data); }
722
1009
 
723
1010
  BOOST_INTRUSIVE_FORCEINLINE value_traits &priv_value_traits()
724
- { return this->data; }
1011
+ { return static_cast<value_traits &>(this->m_data); }
725
1012
 
726
- //bucket_traits
1013
+ //value traits
727
1014
  //
728
1015
  BOOST_INTRUSIVE_FORCEINLINE const bucket_traits &priv_bucket_traits() const
729
- { return this->data.bucket_traits_; }
1016
+ { return static_cast<const bucket_traits &>(this->m_data); }
730
1017
 
731
- BOOST_INTRUSIVE_FORCEINLINE bucket_traits &priv_bucket_traits()
732
- { return this->data.bucket_traits_; }
1018
+ BOOST_INTRUSIVE_FORCEINLINE bucket_traits& priv_bucket_traits()
1019
+ { return static_cast<bucket_traits&>(this->m_data); }
733
1020
 
734
1021
  //bucket operations
735
1022
  BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_bucket_pointer() const BOOST_NOEXCEPT
736
1023
  { return this->priv_bucket_traits().bucket_begin(); }
737
1024
 
738
- std::size_t priv_bucket_count() const BOOST_NOEXCEPT
739
- { return this->priv_bucket_traits().bucket_count(); }
1025
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_usable_bucket_count() const BOOST_NOEXCEPT
1026
+ {
1027
+ BOOST_IF_CONSTEXPR(bucket_overhead){
1028
+ const std::size_t n = this->priv_bucket_traits().bucket_count();
1029
+ return n - std::size_t(n != 0)*bucket_overhead;
1030
+ }
1031
+ else{
1032
+ return this->priv_bucket_traits().bucket_count();
1033
+ }
1034
+ }
1035
+
1036
+ BOOST_INTRUSIVE_FORCEINLINE bucket_type &priv_bucket(std::size_t n) const BOOST_NOEXCEPT
1037
+ {
1038
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(n < this->priv_usable_bucket_count());
1039
+ return this->priv_bucket_pointer()[std::ptrdiff_t(n)];
1040
+ }
1041
+
1042
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_bucket_ptr(std::size_t n) const BOOST_NOEXCEPT
1043
+ { return pointer_traits<bucket_ptr>::pointer_to(this->priv_bucket(n)); }
1044
+
1045
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_past_usable_bucket_ptr() const
1046
+ { return this->priv_bucket_pointer() + std::ptrdiff_t(priv_usable_bucket_count()); }
740
1047
 
741
- BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_invalid_bucket() const
1048
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_invalid_bucket_ptr() const
742
1049
  {
743
- const bucket_traits &rbt = this->priv_bucket_traits();
744
- return rbt.bucket_begin() + rbt.bucket_count();
1050
+ BOOST_IF_CONSTEXPR(LinearBuckets) {
1051
+ return bucket_ptr();
1052
+ }
1053
+ else{
1054
+ return this->priv_past_usable_bucket_ptr();
1055
+ }
1056
+ }
1057
+
1058
+ BOOST_INTRUSIVE_FORCEINLINE void priv_set_sentinel_bucket() const
1059
+ {
1060
+ BOOST_IF_CONSTEXPR(LinearBuckets) {
1061
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_bucket_traits().bucket_count() > 1);
1062
+ bucket_type &b = this->priv_bucket_pointer()[std::ptrdiff_t(this->priv_usable_bucket_count())];
1063
+ slist_node_algorithms::set_sentinel(b.get_node_ptr());
1064
+ }
745
1065
  }
746
1066
 
747
- BOOST_INTRUSIVE_FORCEINLINE siterator priv_invalid_local_it() const
748
- { return this->priv_bucket_traits().bucket_begin()->before_begin(); }
1067
+ BOOST_INTRUSIVE_FORCEINLINE void priv_unset_sentinel_bucket() const
1068
+ {
1069
+ BOOST_IF_CONSTEXPR(LinearBuckets) {
1070
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_bucket_traits().bucket_count() > 1);
1071
+ bucket_type& b = this->priv_bucket_pointer()[std::ptrdiff_t(this->priv_usable_bucket_count())];
1072
+ slist_node_algorithms::init_header(b.get_node_ptr());
1073
+ }
1074
+ }
1075
+
1076
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit() const
1077
+ { return priv_end_sit(linear_buckets_t()); }
1078
+
1079
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit(detail::true_) const
1080
+ { return siterator(this->priv_bucket_pointer() + std::ptrdiff_t(this->priv_bucket_traits().bucket_count() - bucket_overhead)); }
1081
+
1082
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_end_sit(detail::false_) const
1083
+ { return siterator(this->priv_bucket_pointer()->get_node_ptr()); }
1084
+
1085
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbegin(std::size_t n) const
1086
+ { siterator s(this->priv_bucket_lbbegin(n)); return ++s; }
1087
+
1088
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbbegin(std::size_t n) const
1089
+ { return this->sit_bbegin(this->priv_bucket(n)); }
1090
+
1091
+ BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lend(std::size_t n) const
1092
+ { return this->sit_end(this->priv_bucket(n)); }
1093
+
1094
+ BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_bucket_size(std::size_t n) const
1095
+ { return slist_node_algorithms::count(this->priv_bucket(n).get_node_ptr())-1u; }
1096
+
1097
+ BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(std::size_t n) const
1098
+ { return slist_node_algorithms::is_empty(this->priv_bucket(n).get_node_ptr()); }
1099
+
1100
+ BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(bucket_ptr p) const
1101
+ { return slist_node_algorithms::is_empty(p->get_node_ptr()); }
1102
+
1103
+ static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbegin(bucket_type &b)
1104
+ { return siterator(slist_node_traits::get_next(b.get_node_ptr())); }
1105
+
1106
+ static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lbbegin(bucket_type& b)
1107
+ { return siterator(b.get_node_ptr()); }
1108
+
1109
+ static BOOST_INTRUSIVE_FORCEINLINE siterator priv_bucket_lend(bucket_type& b)
1110
+ { return siterator(slist_node_algorithms::end_node(b.get_node_ptr())); }
1111
+
1112
+ static BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_bucket_size(const bucket_type& b)
1113
+ { return slist_node_algorithms::count(b.get_node_ptr())-1u; }
1114
+
1115
+ static BOOST_INTRUSIVE_FORCEINLINE bool priv_bucket_empty(const bucket_type& b)
1116
+ { return slist_node_algorithms::is_empty(b.get_node_ptr()); }
749
1117
 
750
1118
  template<class NodeDisposer>
751
- static std::size_t priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey
1119
+ static std::size_t priv_erase_from_single_bucket
1120
+ (bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::true_) //optimize multikey
752
1121
  {
753
1122
  std::size_t n = 0;
754
1123
  siterator const sfirst(++siterator(sbefore_first));
755
1124
  if(sfirst != slast){
756
- node_ptr const nf = detail::dcast_bucket_ptr<node>(sfirst.pointed_node());
757
- node_ptr const nl = detail::dcast_bucket_ptr<node>(slast.pointed_node());
758
- node_ptr const ne = detail::dcast_bucket_ptr<node>(b.end().pointed_node());
1125
+ node_ptr const nf = dcast_bucket_ptr<node>(sfirst.pointed_node());
1126
+ node_ptr const nl = dcast_bucket_ptr<node>(slast.pointed_node());
1127
+ slist_node_ptr const ne = (priv_bucket_lend(b)).pointed_node();
759
1128
 
760
- if(group_functions_t::next_group_if_first_in_group(nf) != nf) {
761
- // The node is at the beginning of a group.
1129
+ if(group_functions_t::is_first_in_group(nf)) {
1130
+ // The first node is at the beginning of a group.
762
1131
  if(nl != ne){
763
1132
  group_functions_t::split_group(nl);
764
1133
  }
@@ -766,52 +1135,42 @@ struct bucket_plus_vtraits
766
1135
  else {
767
1136
  node_ptr const group1 = group_functions_t::split_group(nf);
768
1137
  if(nl != ne) {
769
- node_ptr const group2 = group_functions_t::split_group(ne);
1138
+ node_ptr const group2 = group_functions_t::split_group(nl);
770
1139
  if(nf == group2) { //Both first and last in the same group
771
1140
  //so join group1 and group2
772
1141
  node_ptr const end1 = group_traits::get_next(group1);
773
1142
  node_ptr const end2 = group_traits::get_next(group2);
774
1143
  group_traits::set_next(group1, end2);
775
- group_traits::set_next(group2, end1);
1144
+ group_traits::set_next(nl, end1);
776
1145
  }
777
1146
  }
778
1147
  }
779
1148
 
780
- siterator it(++siterator(sbefore_first));
781
- while(it != slast){
782
- node_disposer((it++).pointed_node());
783
- ++n;
784
- }
785
- b.erase_after(sbefore_first, slast);
1149
+ n = slist_node_algorithms::unlink_after_and_dispose(sbefore_first.pointed_node(), slast.pointed_node(), node_disposer);
786
1150
  }
787
1151
  return n;
788
1152
  }
789
1153
 
790
1154
  template<class NodeDisposer>
791
- static std::size_t priv_erase_from_single_bucket(bucket_type &b, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey
1155
+ static std::size_t priv_erase_from_single_bucket
1156
+ (bucket_type &, siterator sbefore_first, siterator slast, NodeDisposer node_disposer, detail::false_) //optimize multikey
792
1157
  {
793
- std::size_t n = 0;
794
- siterator it(++siterator(sbefore_first));
795
- while(it != slast){
796
- node_disposer((it++).pointed_node());
797
- ++n;
798
- }
799
- b.erase_after(sbefore_first, slast);
800
- return n;
1158
+ return slist_node_algorithms::unlink_after_and_dispose(sbefore_first.pointed_node(), slast.pointed_node(), node_disposer);
801
1159
  }
802
1160
 
803
1161
  template<class NodeDisposer>
804
1162
  static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::true_) //optimize multikey
805
1163
  {
806
- node_ptr const ne(detail::dcast_bucket_ptr<node>(b.end().pointed_node()));
807
- node_ptr n(detail::dcast_bucket_ptr<node>(i.pointed_node()));
1164
+ slist_node_ptr const ne(priv_bucket_lend(b).pointed_node());
1165
+ slist_node_ptr const nbb(priv_bucket_lbbegin(b).pointed_node());
1166
+ node_ptr n(dcast_bucket_ptr<node>(i.pointed_node()));
808
1167
  node_ptr pos = node_traits::get_next(group_traits::get_next(n));
809
1168
  node_ptr bn;
810
1169
  node_ptr nn(node_traits::get_next(n));
811
1170
 
812
1171
  if(pos != n) {
813
1172
  //Node is the first of the group
814
- bn = group_functions_t::get_prev_to_first_in_group(ne, n);
1173
+ bn = group_functions_t::get_prev_to_first_in_group(nbb, n);
815
1174
 
816
1175
  //Unlink the rest of the group if it's not the last node of its group
817
1176
  if(nn != ne && group_traits::get_next(nn) == n){
@@ -829,12 +1188,15 @@ struct bucket_plus_vtraits
829
1188
  node_ptr const x(group_algorithms::get_previous_node(n));
830
1189
  group_algorithms::unlink_after(x);
831
1190
  }
832
- b.erase_after_and_dispose(bucket_type::s_iterator_to(*bn), node_disposer);
1191
+ slist_node_algorithms::unlink_after_and_dispose(bn, node_disposer);
833
1192
  }
834
1193
 
835
1194
  template<class NodeDisposer>
836
- BOOST_INTRUSIVE_FORCEINLINE static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //optimize multikey
837
- { b.erase_after_and_dispose(b.previous(i), node_disposer); }
1195
+ BOOST_INTRUSIVE_FORCEINLINE static void priv_erase_node(bucket_type &b, siterator i, NodeDisposer node_disposer, detail::false_) //!optimize multikey
1196
+ {
1197
+ slist_node_ptr bi = slist_node_algorithms::get_previous_node(b.get_node_ptr(), i.pointed_node());
1198
+ slist_node_algorithms::unlink_after_and_dispose(bi, node_disposer);
1199
+ }
838
1200
 
839
1201
  template<class NodeDisposer, bool OptimizeMultikey>
840
1202
  std::size_t priv_erase_node_range( siterator const &before_first_it, std::size_t const first_bucket
@@ -844,19 +1206,19 @@ struct bucket_plus_vtraits
844
1206
  std::size_t num_erased(0);
845
1207
  siterator last_step_before_it;
846
1208
  if(first_bucket != last_bucket){
847
- bucket_type *b = (&this->priv_bucket_pointer()[0]);
1209
+ bucket_type *b = &this->priv_bucket(0);
848
1210
  num_erased += this->priv_erase_from_single_bucket
849
- (b[first_bucket], before_first_it, b[first_bucket].end(), node_disposer, optimize_multikey_tag);
1211
+ (b[first_bucket], before_first_it, this->priv_bucket_lend(first_bucket), node_disposer, optimize_multikey_tag);
850
1212
  for(std::size_t i = 0, n = (last_bucket - first_bucket - 1); i != n; ++i){
851
1213
  num_erased += this->priv_erase_whole_bucket(b[first_bucket+i+1], node_disposer);
852
1214
  }
853
- last_step_before_it = b[last_bucket].before_begin();
1215
+ last_step_before_it = this->priv_bucket_lbbegin(last_bucket);
854
1216
  }
855
1217
  else{
856
1218
  last_step_before_it = before_first_it;
857
1219
  }
858
1220
  num_erased += this->priv_erase_from_single_bucket
859
- (this->priv_bucket_pointer()[last_bucket], last_step_before_it, last_it, node_disposer, optimize_multikey_tag);
1221
+ (this->priv_bucket(last_bucket), last_step_before_it, last_it, node_disposer, optimize_multikey_tag);
860
1222
  return num_erased;
861
1223
  }
862
1224
 
@@ -865,89 +1227,74 @@ struct bucket_plus_vtraits
865
1227
  //First find the last node of p's group.
866
1228
  //This requires checking the first node of the next group or
867
1229
  //the bucket node.
868
- slist_node_ptr end_ptr(b.end().pointed_node());
869
- node_ptr possible_end(node_traits::get_next( detail::dcast_bucket_ptr<node>(end_ptr)));
870
- node_ptr last_node_group(possible_end);
1230
+ slist_node_ptr end_ptr(sit_end(b).pointed_node());
1231
+ slist_node_ptr last_node_group(b.get_node_ptr());
1232
+ slist_node_ptr possible_end(slist_node_traits::get_next(last_node_group));
871
1233
 
872
1234
  while(end_ptr != possible_end){
873
- last_node_group = group_traits::get_next(detail::dcast_bucket_ptr<node>(possible_end));
874
- possible_end = node_traits::get_next(last_node_group);
1235
+ last_node_group = group_traits::get_next(dcast_bucket_ptr<node>(possible_end));
1236
+ possible_end = slist_node_traits::get_next(last_node_group);
875
1237
  }
876
- return bucket_type::s_iterator_to(*last_node_group);
1238
+ return siterator(last_node_group);
877
1239
  }
878
1240
 
879
- template<class NodeDisposer>
880
- std::size_t priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer)
881
- {
882
- std::size_t num_erased = 0;
883
- siterator b_begin(b.before_begin());
884
- siterator nxt(b_begin);
885
- ++nxt;
886
- siterator const end_sit(b.end());
887
- while(nxt != end_sit){
888
- //No need to init group links as we'll delete all bucket nodes
889
- nxt = bucket_type::s_erase_after_and_dispose(b_begin, node_disposer);
890
- ++num_erased;
891
- }
892
- return num_erased;
1241
+ BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey
1242
+ {
1243
+ slist_node_ptr p = b.get_node_ptr();
1244
+ return siterator(slist_node_algorithms::get_previous_node(p, slist_node_algorithms::end_node(p)));
893
1245
  }
894
1246
 
895
- BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_last(bucket_type &b, detail::false_) //NOT optimize multikey
896
- { return b.previous(b.end()); }
1247
+ template<class NodeDisposer>
1248
+ static BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_erase_whole_bucket(bucket_type &b, NodeDisposer node_disposer)
1249
+ { return slist_node_algorithms::detach_and_dispose(b.get_node_ptr(), node_disposer); }
897
1250
 
898
1251
  static siterator priv_get_previous(bucket_type &b, siterator i, detail::true_) //optimize multikey
899
1252
  {
900
- node_ptr const elem(detail::dcast_bucket_ptr<node>(i.pointed_node()));
1253
+ node_ptr const elem(dcast_bucket_ptr<node>(i.pointed_node()));
901
1254
  node_ptr const prev_in_group(group_traits::get_next(elem));
902
1255
  bool const first_in_group = node_traits::get_next(prev_in_group) != elem;
903
- typename bucket_type::node &n = first_in_group
904
- ? *group_functions_t::get_prev_to_first_in_group(b.end().pointed_node(), elem)
905
- : *group_traits::get_next(elem)
1256
+ slist_node_ptr n = first_in_group
1257
+ ? group_functions_t::get_prev_to_first_in_group(b.get_node_ptr(), elem)
1258
+ : group_traits::get_next(elem)
906
1259
  ;
907
- return bucket_type::s_iterator_to(n);
1260
+ return siterator(n);
908
1261
  }
909
1262
 
910
1263
  BOOST_INTRUSIVE_FORCEINLINE static siterator priv_get_previous(bucket_type &b, siterator i, detail::false_) //NOT optimize multikey
911
- { return b.previous(i); }
1264
+ { return siterator(slist_node_algorithms::get_previous_node(b.get_node_ptr(), i.pointed_node())); }
912
1265
 
913
- std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_) //optimize multikey
1266
+ template<class Disposer>
1267
+ struct typeof_node_disposer
914
1268
  {
915
- const bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1);
916
- slist_node_ptr bb = group_functions_t::get_bucket_before_begin
917
- ( f->end().pointed_node()
918
- , l->end().pointed_node()
919
- , detail::dcast_bucket_ptr<node>(it.pointed_node()));
920
- //Now get the bucket_impl from the iterator
921
- const bucket_type &b = static_cast<const bucket_type&>
922
- (bucket_type::slist_type::container_from_end_iterator(bucket_type::s_iterator_to(*bb)));
923
- //Now just calculate the index b has in the bucket array
924
- return static_cast<std::size_t>(&b - &*f);
925
- }
1269
+ typedef node_cast_adaptor
1270
+ < detail::node_disposer< Disposer, value_traits, CommonSListAlgorithms>
1271
+ , slist_node_ptr, node_ptr > type;
1272
+ };
926
1273
 
927
- std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::false_) //NO optimize multikey
1274
+ template<class Disposer>
1275
+ BOOST_INTRUSIVE_FORCEINLINE typename typeof_node_disposer<Disposer>::type
1276
+ make_node_disposer(const Disposer &disposer) const
928
1277
  {
929
- bucket_ptr f(this->priv_bucket_pointer()), l(f + this->priv_bucket_count() - 1);
930
- slist_node_ptr first_ptr(f->cend().pointed_node())
931
- , last_ptr(l->cend().pointed_node());
1278
+ typedef typename typeof_node_disposer<Disposer>::type return_t;
1279
+ return return_t(disposer, &this->priv_value_traits());
1280
+ }
932
1281
 
933
- //The end node is embedded in the singly linked list:
934
- //iterate until we reach it.
935
- while(!(std::less_equal<slist_node_ptr>()(first_ptr, it.pointed_node()) &&
936
- std::less_equal<slist_node_ptr>()(it.pointed_node(), last_ptr))){
937
- ++it;
938
- }
939
- //Now get the bucket_impl from the iterator
940
- const bucket_type &b = static_cast<const bucket_type&>
941
- (bucket_type::container_from_end_iterator(it));
1282
+ static BOOST_INTRUSIVE_FORCEINLINE bucket_ptr to_ptr(bucket_type &b)
1283
+ { return pointer_traits<bucket_ptr>::pointer_to(b); }
942
1284
 
943
- //Now just calculate the index b has in the bucket array
944
- return static_cast<std::size_t>(&b - &*f);
945
- }
1285
+ static BOOST_INTRUSIVE_FORCEINLINE siterator sit_bbegin(bucket_type& b)
1286
+ { return siterator(b.get_node_ptr()); }
1287
+
1288
+ static BOOST_INTRUSIVE_FORCEINLINE siterator sit_begin(bucket_type& b)
1289
+ { return siterator(b.begin_ptr()); }
946
1290
 
947
- BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_) //store_hash
948
- { return node_traits::get_hash(detail::dcast_bucket_ptr<node>(n)); }
1291
+ static BOOST_INTRUSIVE_FORCEINLINE siterator sit_end(bucket_type& b)
1292
+ { return siterator(slist_node_algorithms::end_node(b.get_node_ptr())); }
949
1293
 
950
- BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(slist_node_ptr, detail::false_) //NO store_hash
1294
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(siterator s, detail::true_) //store_hash
1295
+ { return node_traits::get_hash(dcast_bucket_ptr<node>(s.pointed_node())); }
1296
+
1297
+ BOOST_INTRUSIVE_FORCEINLINE static std::size_t priv_stored_hash(siterator, detail::false_) //NO store_hash
951
1298
  { return std::size_t(-1); }
952
1299
 
953
1300
  BOOST_INTRUSIVE_FORCEINLINE node &priv_value_to_node(reference v)
@@ -956,21 +1303,36 @@ struct bucket_plus_vtraits
956
1303
  BOOST_INTRUSIVE_FORCEINLINE const node &priv_value_to_node(const_reference v) const
957
1304
  { return *this->priv_value_traits().to_node_ptr(v); }
958
1305
 
959
- BOOST_INTRUSIVE_FORCEINLINE reference priv_value_from_slist_node(slist_node_ptr n)
960
- { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
1306
+ BOOST_INTRUSIVE_FORCEINLINE node_ptr priv_value_to_node_ptr(reference v)
1307
+ { return this->priv_value_traits().to_node_ptr(v); }
1308
+
1309
+ BOOST_INTRUSIVE_FORCEINLINE const_node_ptr priv_value_to_node_ptr(const_reference v) const
1310
+ { return this->priv_value_traits().to_node_ptr(v); }
1311
+
1312
+ BOOST_INTRUSIVE_FORCEINLINE reference priv_value_from_siterator(siterator s)
1313
+ { return *this->priv_value_traits().to_value_ptr(dcast_bucket_ptr<node>(s.pointed_node())); }
961
1314
 
962
- BOOST_INTRUSIVE_FORCEINLINE const_reference priv_value_from_slist_node(slist_node_ptr n) const
963
- { return *this->priv_value_traits().to_value_ptr(detail::dcast_bucket_ptr<node>(n)); }
1315
+ BOOST_INTRUSIVE_FORCEINLINE const_reference priv_value_from_siterator(siterator s) const
1316
+ { return *this->priv_value_traits().to_value_ptr(dcast_bucket_ptr<node>(s.pointed_node())); }
1317
+
1318
+ static void priv_init_buckets(const bucket_ptr buckets_ptr, const std::size_t bucket_cnt)
1319
+ {
1320
+ bucket_ptr buckets_it = buckets_ptr;
1321
+ for (std::size_t bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i) {
1322
+ slist_node_algorithms::init_header(buckets_it->get_node_ptr());
1323
+ }
1324
+ }
964
1325
 
965
1326
  void priv_clear_buckets(const bucket_ptr buckets_ptr, const std::size_t bucket_cnt)
966
1327
  {
967
1328
  bucket_ptr buckets_it = buckets_ptr;
968
1329
  for(std::size_t bucket_i = 0; bucket_i != bucket_cnt; ++buckets_it, ++bucket_i){
1330
+ bucket_type &b = *buckets_it;
969
1331
  BOOST_IF_CONSTEXPR(safemode_or_autounlink){
970
- buckets_it->clear_and_dispose(detail::init_disposer<node_algorithms>());
1332
+ slist_node_algorithms::detach_and_dispose(b.get_node_ptr(), this->make_node_disposer(detail::null_disposer()));
971
1333
  }
972
1334
  else{
973
- buckets_it->clear();
1335
+ slist_node_algorithms::init_header(b.get_node_ptr());
974
1336
  }
975
1337
  }
976
1338
  }
@@ -978,28 +1340,35 @@ struct bucket_plus_vtraits
978
1340
  BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const //For store_hash == true
979
1341
  { return node_traits::get_hash(this->priv_value_traits().to_node_ptr(v)); }
980
1342
 
981
- typedef hashtable_iterator<bucket_plus_vtraits, false> iterator;
982
- typedef hashtable_iterator<bucket_plus_vtraits, true> const_iterator;
1343
+ typedef hashtable_iterator<bucket_plus_vtraits, LinearBuckets, false> iterator;
1344
+ typedef hashtable_iterator<bucket_plus_vtraits, LinearBuckets, true> const_iterator;
983
1345
 
984
1346
  BOOST_INTRUSIVE_FORCEINLINE iterator end() BOOST_NOEXCEPT
985
- { return iterator(this->priv_invalid_local_it(), 0); }
1347
+ { return this->build_iterator(this->priv_end_sit(), bucket_ptr()); }
986
1348
 
987
1349
  BOOST_INTRUSIVE_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT
988
- { return this->cend(); }
1350
+ { return this->cend(); }
989
1351
 
990
1352
  BOOST_INTRUSIVE_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT
991
- { return const_iterator(this->priv_invalid_local_it(), 0); }
1353
+ { return this->build_const_iterator(this->priv_end_sit(), bucket_ptr()); }
992
1354
 
993
- //Public functions:
994
- struct data_type : public ValueTraits
995
- {
996
- template<class BucketTraitsType>
997
- BOOST_INTRUSIVE_FORCEINLINE data_type(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits)
998
- : ValueTraits(val_traits), bucket_traits_(::boost::forward<BucketTraitsType>(b_traits))
999
- {}
1355
+ BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr p)
1356
+ { return this->build_iterator(s, p, linear_buckets_t()); }
1357
+
1358
+ BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr p, detail::true_) //linear buckets
1359
+ { return iterator(s, p, this->priv_value_traits_ptr()); }
1360
+
1361
+ BOOST_INTRUSIVE_FORCEINLINE iterator build_iterator(siterator s, bucket_ptr, detail::false_) //!linear buckets
1362
+ { return iterator(s, &this->get_bucket_value_traits()); }
1000
1363
 
1001
- bucket_traits bucket_traits_;
1002
- } data;
1364
+ BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr p) const
1365
+ { return this->build_const_iterator(s, p, linear_buckets_t()); }
1366
+
1367
+ BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr p, detail::true_) const //linear buckets
1368
+ { return const_iterator(s, p, this->priv_value_traits_ptr()); }
1369
+
1370
+ BOOST_INTRUSIVE_FORCEINLINE const_iterator build_const_iterator(siterator s, bucket_ptr, detail::false_) const //!linear buckets
1371
+ { return const_iterator(s, &this->get_bucket_value_traits()); }
1003
1372
  };
1004
1373
 
1005
1374
  template<class Hash, class>
@@ -1023,7 +1392,7 @@ struct get_equal_to
1023
1392
  template<class T>
1024
1393
  struct get_equal_to<void, T>
1025
1394
  {
1026
- typedef std::equal_to<T> type;
1395
+ typedef value_equal<T> type;
1027
1396
  };
1028
1397
 
1029
1398
  template<class KeyOfValue, class T>
@@ -1065,18 +1434,24 @@ struct hash_key_equal
1065
1434
 
1066
1435
  //bucket_hash_t
1067
1436
  //Stores bucket_plus_vtraits plust the hash function
1068
- template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class BucketTraits>
1437
+ template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class BucketTraits, bool LinearBuckets>
1069
1438
  struct bucket_hash_t
1070
1439
  //Use public inheritance to avoid MSVC bugs with closures
1071
1440
  : public detail::ebo_functor_holder
1072
- <typename hash_key_hash < typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits::value_type
1441
+ <typename hash_key_hash < typename bucket_plus_vtraits<ValueTraits,BucketTraits, LinearBuckets >::value_traits::value_type
1073
1442
  , VoidOrKeyOfValue
1074
1443
  , VoidOrKeyHash
1075
1444
  >::type
1076
1445
  >
1077
- , bucket_plus_vtraits<ValueTraits, BucketTraits> //4
1446
+ , bucket_plus_vtraits<ValueTraits, BucketTraits, LinearBuckets> //4
1078
1447
  {
1079
- typedef typename bucket_plus_vtraits<ValueTraits,BucketTraits>::value_traits value_traits;
1448
+ private:
1449
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_t)
1450
+
1451
+ public:
1452
+
1453
+ typedef typename bucket_plus_vtraits
1454
+ <ValueTraits,BucketTraits, LinearBuckets>::value_traits value_traits;
1080
1455
  typedef typename value_traits::value_type value_type;
1081
1456
  typedef typename value_traits::node_traits node_traits;
1082
1457
  typedef hash_key_hash
@@ -1085,18 +1460,23 @@ struct bucket_hash_t
1085
1460
  typedef typename hash_key_types_base<value_type, VoidOrKeyOfValue>::key_of_value key_of_value;
1086
1461
 
1087
1462
  typedef BucketTraits bucket_traits;
1088
- typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
1463
+ typedef bucket_plus_vtraits<ValueTraits, BucketTraits, LinearBuckets> bucket_plus_vtraits_t;
1089
1464
  typedef detail::ebo_functor_holder<hasher> base_t;
1090
1465
 
1091
- template<class BucketTraitsType>
1092
- BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h)
1093
- : detail::ebo_functor_holder<hasher>(h), bucket_plus_vtraits_t(val_traits, ::boost::forward<BucketTraitsType>(b_traits))
1466
+ BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h)
1467
+ : base_t(h)
1468
+ , bucket_plus_vtraits_t(val_traits, b_traits)
1469
+ {}
1470
+
1471
+ BOOST_INTRUSIVE_FORCEINLINE bucket_hash_t(BOOST_RV_REF(bucket_hash_t) other)
1472
+ : base_t(BOOST_MOVE_BASE(base_t, other))
1473
+ , bucket_plus_vtraits_t(BOOST_MOVE_BASE(bucket_plus_vtraits_t, other))
1094
1474
  {}
1095
1475
 
1096
1476
  BOOST_INTRUSIVE_FORCEINLINE const hasher &priv_hasher() const
1097
1477
  { return this->base_t::get(); }
1098
1478
 
1099
- hasher &priv_hasher()
1479
+ BOOST_INTRUSIVE_FORCEINLINE hasher &priv_hasher()
1100
1480
  { return this->base_t::get(); }
1101
1481
 
1102
1482
  using bucket_plus_vtraits_t::priv_stored_or_compute_hash; //For store_hash == true
@@ -1105,11 +1485,12 @@ struct bucket_hash_t
1105
1485
  { return this->priv_hasher()(key_of_value()(v)); }
1106
1486
  };
1107
1487
 
1108
- template<class ValueTraits, class BucketTraits, class VoidOrKeyOfValue, class VoidOrKeyEqual>
1488
+ template<class ValueTraits, class BucketTraits, class VoidOrKeyOfValue, class VoidOrKeyEqual, bool LinearBuckets>
1109
1489
  struct hashtable_equal_holder
1110
1490
  {
1111
1491
  typedef detail::ebo_functor_holder
1112
- < typename hash_key_equal < typename bucket_plus_vtraits<ValueTraits, BucketTraits>::value_traits::value_type
1492
+ < typename hash_key_equal < typename bucket_plus_vtraits
1493
+ <ValueTraits, BucketTraits, LinearBuckets>::value_traits::value_type
1113
1494
  , VoidOrKeyOfValue
1114
1495
  , VoidOrKeyEqual
1115
1496
  >::type
@@ -1120,57 +1501,76 @@ struct hashtable_equal_holder
1120
1501
  //bucket_hash_equal_t
1121
1502
  //Stores bucket_hash_t and the equality function when the first
1122
1503
  //non-empty bucket shall not be cached.
1123
- template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, bool>
1504
+ template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, bool LinearBuckets, bool>
1124
1505
  struct bucket_hash_equal_t
1125
1506
  //Use public inheritance to avoid MSVC bugs with closures
1126
- : public bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //3
1127
- , public hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type //equal
1507
+ : public bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits, LinearBuckets> //3
1508
+ , public hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual, LinearBuckets>::type //equal
1128
1509
  {
1510
+ private:
1511
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_equal_t)
1512
+
1513
+ public:
1129
1514
  typedef typename hashtable_equal_holder
1130
- <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
1131
- typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
1132
- typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
1133
- typedef ValueTraits value_traits;
1134
- typedef typename equal_holder_t::functor_type key_equal;
1135
- typedef typename bucket_hash_type::hasher hasher;
1136
- typedef BucketTraits bucket_traits;
1137
- typedef typename bucket_plus_vtraits_t::slist_impl slist_impl;
1138
- typedef typename slist_impl::iterator siterator;
1139
- typedef bucket_impl<slist_impl> bucket_type;
1140
- typedef typename detail::unordered_bucket_ptr_impl<value_traits>::type bucket_ptr;
1141
-
1142
- template<class BucketTraitsType>
1143
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
1144
- : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
1515
+ < ValueTraits, BucketTraits, VoidOrKeyOfValue
1516
+ , VoidOrKeyEqual, LinearBuckets>::type equal_holder_t;
1517
+ typedef bucket_hash_t< ValueTraits, VoidOrKeyOfValue
1518
+ , VoidOrKeyHash, BucketTraits
1519
+ , LinearBuckets> bucket_hash_type;
1520
+ typedef bucket_plus_vtraits
1521
+ <ValueTraits, BucketTraits, LinearBuckets> bucket_plus_vtraits_t;
1522
+ typedef ValueTraits value_traits;
1523
+ typedef typename equal_holder_t::functor_type key_equal;
1524
+ typedef typename bucket_hash_type::hasher hasher;
1525
+ typedef BucketTraits bucket_traits;
1526
+ typedef typename bucket_plus_vtraits_t::siterator siterator;
1527
+ typedef typename bucket_plus_vtraits_t::const_siterator const_siterator;
1528
+ typedef typename bucket_plus_vtraits_t::bucket_type bucket_type;
1529
+ typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms;
1530
+ typedef typename unordered_bucket_ptr_impl
1531
+ <value_traits>::type bucket_ptr;
1532
+
1533
+ bucket_hash_equal_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h, const key_equal &e)
1534
+ : bucket_hash_type(val_traits, b_traits, h)
1145
1535
  , equal_holder_t(e)
1146
1536
  {}
1147
1537
 
1538
+ BOOST_INTRUSIVE_FORCEINLINE bucket_hash_equal_t(BOOST_RV_REF(bucket_hash_equal_t) other)
1539
+ : bucket_hash_type(BOOST_MOVE_BASE(bucket_hash_type, other))
1540
+ , equal_holder_t(BOOST_MOVE_BASE(equal_holder_t, other))
1541
+ {}
1542
+
1148
1543
  BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_cache()
1149
- { return this->bucket_hash_type::priv_bucket_pointer(); }
1544
+ { return this->priv_bucket_pointer(); }
1545
+
1546
+ BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr)
1547
+ {}
1150
1548
 
1151
- BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(const bucket_ptr &)
1549
+ BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t)
1152
1550
  {}
1153
1551
 
1154
1552
  BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num()
1155
1553
  { return 0u; }
1156
1554
 
1157
- BOOST_INTRUSIVE_FORCEINLINE void priv_initialize_cache()
1555
+ BOOST_INTRUSIVE_FORCEINLINE void priv_init_cache()
1158
1556
  {}
1159
1557
 
1160
1558
  BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &)
1161
1559
  {}
1162
1560
 
1163
- siterator priv_begin() const
1561
+ siterator priv_begin(bucket_ptr &pbucketptr) const
1164
1562
  {
1165
1563
  std::size_t n = 0;
1166
- std::size_t bucket_cnt = this->bucket_hash_type::priv_bucket_count();
1564
+ std::size_t bucket_cnt = this->priv_usable_bucket_count();
1167
1565
  for (n = 0; n < bucket_cnt; ++n){
1168
- bucket_type &b = this->bucket_hash_type::priv_bucket_pointer()[n];
1169
- if(!b.empty()){
1170
- return b.begin();
1566
+ bucket_type &b = this->priv_bucket(n);
1567
+ if(!slist_node_algorithms::is_empty(b.get_node_ptr())){
1568
+ pbucketptr = this->to_ptr(b);
1569
+ return siterator(b.begin_ptr());
1171
1570
  }
1172
1571
  }
1173
- return this->bucket_hash_type::priv_invalid_local_it();
1572
+ pbucketptr = this->priv_invalid_bucket_ptr();
1573
+ return this->priv_end_sit();
1174
1574
  }
1175
1575
 
1176
1576
  BOOST_INTRUSIVE_FORCEINLINE void priv_insertion_update_cache(std::size_t)
@@ -1179,6 +1579,9 @@ struct bucket_hash_equal_t
1179
1579
  BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache_range(std::size_t, std::size_t)
1180
1580
  {}
1181
1581
 
1582
+ BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache(bucket_ptr)
1583
+ {}
1584
+
1182
1585
  BOOST_INTRUSIVE_FORCEINLINE void priv_erasure_update_cache()
1183
1586
  {}
1184
1587
 
@@ -1192,65 +1595,82 @@ struct bucket_hash_equal_t
1192
1595
  //bucket_hash_equal_t
1193
1596
  //Stores bucket_hash_t and the equality function when the first
1194
1597
  //non-empty bucket shall be cached.
1195
- template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits> //cache_begin == true version
1196
- struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, true>
1598
+ template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, bool LinearBuckets> //cache_begin == true version
1599
+ struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, LinearBuckets, true>
1197
1600
  //Use public inheritance to avoid MSVC bugs with closures
1198
- : bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> //2
1199
- , hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type
1601
+ : public bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits, LinearBuckets> //2
1602
+ , public hashtable_equal_holder<ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual, LinearBuckets>::type
1200
1603
  {
1604
+ private:
1605
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(bucket_hash_equal_t)
1606
+
1607
+ public:
1608
+
1201
1609
  typedef typename hashtable_equal_holder
1202
- <ValueTraits, BucketTraits, VoidOrKeyOfValue, VoidOrKeyEqual>::type equal_holder_t;
1610
+ < ValueTraits, BucketTraits
1611
+ , VoidOrKeyOfValue, VoidOrKeyEqual, LinearBuckets>::type equal_holder_t;
1203
1612
 
1204
- typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
1613
+ typedef bucket_plus_vtraits
1614
+ < ValueTraits, BucketTraits, LinearBuckets> bucket_plus_vtraits_t;
1205
1615
  typedef ValueTraits value_traits;
1206
1616
  typedef typename equal_holder_t::functor_type key_equal;
1207
- typedef bucket_hash_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, BucketTraits> bucket_hash_type;
1617
+ typedef bucket_hash_t
1618
+ < ValueTraits, VoidOrKeyOfValue
1619
+ , VoidOrKeyHash, BucketTraits, LinearBuckets> bucket_hash_type;
1208
1620
  typedef typename bucket_hash_type::hasher hasher;
1209
1621
  typedef BucketTraits bucket_traits;
1210
- typedef typename bucket_plus_vtraits_t::slist_impl::iterator siterator;
1622
+ typedef typename bucket_plus_vtraits_t::siterator siterator;
1623
+ typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms;
1211
1624
 
1212
- template<class BucketTraitsType>
1213
- bucket_hash_equal_t(const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits, const hasher & h, const key_equal &e)
1214
- : bucket_hash_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h)
1625
+ bucket_hash_equal_t(const ValueTraits &val_traits, const bucket_traits &b_traits, const hasher & h, const key_equal &e)
1626
+ : bucket_hash_type(val_traits, b_traits, h)
1215
1627
  , equal_holder_t(e)
1216
1628
  {}
1217
1629
 
1218
- typedef typename detail::unordered_bucket_ptr_impl
1219
- <typename bucket_hash_type::value_traits>::type bucket_ptr;
1630
+ BOOST_INTRUSIVE_FORCEINLINE bucket_hash_equal_t(BOOST_RV_REF(bucket_hash_equal_t) other)
1631
+ : bucket_hash_type(BOOST_MOVE_BASE(bucket_hash_type, other))
1632
+ , equal_holder_t(BOOST_MOVE_BASE(equal_holder_t, other))
1633
+ {}
1220
1634
 
1221
- BOOST_INTRUSIVE_FORCEINLINE bucket_ptr &priv_get_cache()
1222
- { return cached_begin_; }
1635
+ typedef typename unordered_bucket_ptr_impl
1636
+ <typename bucket_hash_type::value_traits>::type bucket_ptr;
1223
1637
 
1224
- BOOST_INTRUSIVE_FORCEINLINE const bucket_ptr &priv_get_cache() const
1638
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_cache() const
1225
1639
  { return cached_begin_; }
1226
1640
 
1227
- BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(const bucket_ptr &p)
1641
+ BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache(bucket_ptr p)
1228
1642
  { cached_begin_ = p; }
1229
1643
 
1644
+ BOOST_INTRUSIVE_FORCEINLINE void priv_set_cache_bucket_num(std::size_t insertion_bucket)
1645
+ {
1646
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(insertion_bucket <= this->priv_usable_bucket_count());
1647
+ this->cached_begin_ = this->priv_bucket_pointer() + std::ptrdiff_t(insertion_bucket);
1648
+ }
1649
+
1230
1650
  BOOST_INTRUSIVE_FORCEINLINE std::size_t priv_get_cache_bucket_num()
1231
- { return this->cached_begin_ - this->bucket_hash_type::priv_bucket_pointer(); }
1651
+ { return std::size_t(this->cached_begin_ - this->priv_bucket_pointer()); }
1232
1652
 
1233
- BOOST_INTRUSIVE_FORCEINLINE void priv_initialize_cache()
1234
- { this->cached_begin_ = this->bucket_hash_type::priv_invalid_bucket(); }
1653
+ BOOST_INTRUSIVE_FORCEINLINE void priv_init_cache()
1654
+ { this->cached_begin_ = this->priv_past_usable_bucket_ptr(); }
1235
1655
 
1236
1656
  BOOST_INTRUSIVE_FORCEINLINE void priv_swap_cache(bucket_hash_equal_t &other)
1237
- {
1238
- ::boost::adl_move_swap(this->cached_begin_, other.cached_begin_);
1239
- }
1657
+ { ::boost::adl_move_swap(this->cached_begin_, other.cached_begin_); }
1240
1658
 
1241
- siterator priv_begin() const
1659
+ siterator priv_begin(bucket_ptr& pbucketptr) const
1242
1660
  {
1243
- if(this->cached_begin_ == this->bucket_hash_type::priv_invalid_bucket()){
1244
- return this->bucket_hash_type::priv_invalid_local_it();
1661
+ pbucketptr = this->cached_begin_;
1662
+ if(this->cached_begin_ == this->priv_past_usable_bucket_ptr()){
1663
+ return this->priv_end_sit();
1245
1664
  }
1246
1665
  else{
1247
- return this->cached_begin_->begin();
1666
+ return siterator(cached_begin_->begin_ptr());
1248
1667
  }
1249
1668
  }
1250
1669
 
1251
1670
  void priv_insertion_update_cache(std::size_t insertion_bucket)
1252
1671
  {
1253
- bucket_ptr p = this->bucket_hash_type::priv_bucket_pointer() + insertion_bucket;
1672
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(insertion_bucket < this->priv_usable_bucket_count());
1673
+ bucket_ptr p = this->priv_bucket_pointer() + std::ptrdiff_t(insertion_bucket);
1254
1674
  if(p < this->cached_begin_){
1255
1675
  this->cached_begin_ = p;
1256
1676
  }
@@ -1267,24 +1687,30 @@ struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrK
1267
1687
  //If the last bucket is the end, the cache must be updated
1268
1688
  //to the last position if all
1269
1689
  if(this->priv_get_cache_bucket_num() == first_bucket_num &&
1270
- this->bucket_hash_type::priv_bucket_pointer()[first_bucket_num].empty() ){
1271
- this->priv_set_cache(this->bucket_hash_type::priv_bucket_pointer() + last_bucket_num);
1690
+ this->priv_bucket_empty(first_bucket_num) ){
1691
+ this->priv_set_cache(this->priv_bucket_pointer() + std::ptrdiff_t(last_bucket_num));
1692
+ this->priv_erasure_update_cache();
1693
+ }
1694
+ }
1695
+
1696
+ void priv_erasure_update_cache(bucket_ptr first_bucket)
1697
+ {
1698
+ //If the last bucket is the end, the cache must be updated
1699
+ //to the last position if all
1700
+ if (this->priv_get_cache() == first_bucket &&
1701
+ this->priv_bucket_empty(first_bucket)) {
1272
1702
  this->priv_erasure_update_cache();
1273
1703
  }
1274
1704
  }
1275
1705
 
1276
1706
  void priv_erasure_update_cache()
1277
1707
  {
1278
- if(this->cached_begin_ != this->bucket_hash_type::priv_invalid_bucket()){
1279
- std::size_t current_n = this->priv_get_cache() - this->bucket_hash_type::priv_bucket_pointer();
1280
- for( const std::size_t num_buckets = this->bucket_hash_type::priv_bucket_count()
1281
- ; current_n < num_buckets
1282
- ; ++current_n, ++this->priv_get_cache()){
1283
- if(!this->priv_get_cache()->empty()){
1284
- return;
1285
- }
1708
+ const bucket_ptr cache_end = this->priv_past_usable_bucket_ptr();
1709
+ while( cached_begin_ != cache_end) {
1710
+ if (!slist_node_algorithms::is_empty(cached_begin_->get_node_ptr())) {
1711
+ return;
1286
1712
  }
1287
- this->priv_initialize_cache();
1713
+ ++cached_begin_;
1288
1714
  }
1289
1715
  }
1290
1716
 
@@ -1295,19 +1721,27 @@ struct bucket_hash_equal_t<ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrK
1295
1721
  //to maintain minimal container size with compilers like MSVC
1296
1722
  //that have problems with EBO and multiple empty base classes
1297
1723
  template<class DeriveFrom, class SizeType, bool>
1298
- struct hashtable_size_traits_wrapper
1724
+ struct hashtable_size_wrapper
1299
1725
  : public DeriveFrom
1300
1726
  {
1727
+ private:
1728
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper)
1729
+
1730
+ public:
1301
1731
  template<class Base, class Arg0, class Arg1, class Arg2>
1302
- hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
1303
- , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
1304
- : DeriveFrom(::boost::forward<Base>(base)
1305
- , ::boost::forward<Arg0>(arg0)
1306
- , ::boost::forward<Arg1>(arg1)
1307
- , ::boost::forward<Arg2>(arg2))
1732
+ hashtable_size_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
1733
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
1734
+ : DeriveFrom( ::boost::forward<Base>(base)
1735
+ , ::boost::forward<Arg0>(arg0)
1736
+ , ::boost::forward<Arg1>(arg1)
1737
+ , ::boost::forward<Arg2>(arg2))
1308
1738
  {}
1309
1739
  typedef detail::size_holder < true, SizeType> size_traits;//size_traits
1310
1740
 
1741
+ BOOST_INTRUSIVE_FORCEINLINE hashtable_size_wrapper(BOOST_RV_REF(hashtable_size_wrapper) other)
1742
+ : DeriveFrom(BOOST_MOVE_BASE(DeriveFrom, other))
1743
+ {}
1744
+
1311
1745
  size_traits size_traits_;
1312
1746
 
1313
1747
  typedef const size_traits & size_traits_const_t;
@@ -1321,16 +1755,24 @@ struct hashtable_size_traits_wrapper
1321
1755
  };
1322
1756
 
1323
1757
  template<class DeriveFrom, class SizeType>
1324
- struct hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>
1758
+ struct hashtable_size_wrapper<DeriveFrom, SizeType, false>
1325
1759
  : public DeriveFrom
1326
1760
  {
1761
+ private:
1762
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(hashtable_size_wrapper)
1763
+
1764
+ public:
1327
1765
  template<class Base, class Arg0, class Arg1, class Arg2>
1328
- hashtable_size_traits_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
1329
- , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
1330
- : DeriveFrom(::boost::forward<Base>(base)
1331
- , ::boost::forward<Arg0>(arg0)
1332
- , ::boost::forward<Arg1>(arg1)
1333
- , ::boost::forward<Arg2>(arg2))
1766
+ hashtable_size_wrapper( BOOST_FWD_REF(Base) base, BOOST_FWD_REF(Arg0) arg0
1767
+ , BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2)
1768
+ : DeriveFrom( ::boost::forward<Base>(base)
1769
+ , ::boost::forward<Arg0>(arg0)
1770
+ , ::boost::forward<Arg1>(arg1)
1771
+ , ::boost::forward<Arg2>(arg2))
1772
+ {}
1773
+
1774
+ BOOST_INTRUSIVE_FORCEINLINE hashtable_size_wrapper(BOOST_RV_REF(hashtable_size_wrapper) other)
1775
+ : DeriveFrom(BOOST_MOVE_BASE(DeriveFrom, other))
1334
1776
  {}
1335
1777
 
1336
1778
  typedef detail::size_holder< false, SizeType> size_traits;
@@ -1342,32 +1784,43 @@ struct hashtable_size_traits_wrapper<DeriveFrom, SizeType, false>
1342
1784
  { return size_traits(); }
1343
1785
  };
1344
1786
 
1345
- //hashdata_internal
1346
- //Stores bucket_hash_equal_t and split_traits
1347
- template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
1348
- struct hashdata_internal
1349
- : public hashtable_size_traits_wrapper
1350
- < bucket_hash_equal_t
1351
- < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
1352
- , BucketTraits
1353
- , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
1354
- > //2
1355
- , SizeType
1356
- , (BoolFlags & hash_bool_flags::incremental_pos) != 0
1357
- >
1787
+ template< class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash
1788
+ , class VoidOrKeyEqual, class BucketTraits, class SizeType
1789
+ , std::size_t BoolFlags>
1790
+ struct get_hashtable_size_wrapper_bucket
1358
1791
  {
1359
- typedef hashtable_size_traits_wrapper
1792
+ typedef hashtable_size_wrapper
1360
1793
  < bucket_hash_equal_t
1361
1794
  < ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
1362
1795
  , BucketTraits
1796
+ , 0 != (BoolFlags & hash_bool_flags::linear_buckets_pos)
1363
1797
  , 0 != (BoolFlags & hash_bool_flags::cache_begin_pos)
1364
1798
  > //2
1365
1799
  , SizeType
1366
- , (BoolFlags & hash_bool_flags::incremental_pos) != 0
1367
- > internal_type;
1800
+ , (BoolFlags & hash_bool_flags::incremental_pos) != 0 ||
1801
+ (BoolFlags & hash_bool_flags::fastmod_buckets_pos) != 0
1802
+ > type;
1803
+ };
1804
+
1805
+ //hashdata_internal
1806
+ //Stores bucket_hash_equal_t and split_traits
1807
+ template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
1808
+ struct hashdata_internal
1809
+ : public get_hashtable_size_wrapper_bucket
1810
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::type
1811
+ {
1812
+ private:
1813
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(hashdata_internal)
1814
+
1815
+ public:
1816
+ static const bool linear_buckets = 0 != (BoolFlags & hash_bool_flags::linear_buckets_pos);
1817
+ typedef typename get_hashtable_size_wrapper_bucket
1818
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::type internal_type;
1819
+
1368
1820
  typedef typename internal_type::key_equal key_equal;
1369
1821
  typedef typename internal_type::hasher hasher;
1370
- typedef bucket_plus_vtraits<ValueTraits,BucketTraits> bucket_plus_vtraits_t;
1822
+ typedef bucket_plus_vtraits
1823
+ <ValueTraits, BucketTraits, linear_buckets> bucket_plus_vtraits_t;
1371
1824
  typedef SizeType size_type;
1372
1825
  typedef typename internal_type::size_traits split_traits;
1373
1826
  typedef typename bucket_plus_vtraits_t::bucket_ptr bucket_ptr;
@@ -1384,15 +1837,10 @@ struct hashdata_internal
1384
1837
  <const_pointer>::reference const_reference;
1385
1838
  typedef typename value_traits::node_traits node_traits;
1386
1839
  typedef typename node_traits::node node;
1387
- typedef typename node_traits::node_ptr node_ptr;
1388
- typedef typename node_traits::const_node_ptr const_node_ptr;
1389
- typedef detail::node_functions<node_traits> node_functions_t;
1390
- typedef typename get_slist_impl
1391
- <typename reduced_slist_node_traits
1392
- <typename value_traits::node_traits>::type
1393
- >::type slist_impl;
1394
- typedef typename slist_impl::node_algorithms node_algorithms;
1395
- typedef typename slist_impl::node_ptr slist_node_ptr;
1840
+ typedef typename node_traits::node_ptr node_ptr;
1841
+ typedef typename node_traits::const_node_ptr const_node_ptr;
1842
+ typedef typename bucket_plus_vtraits_t::slist_node_algorithms slist_node_algorithms;
1843
+ typedef typename bucket_plus_vtraits_t::slist_node_ptr slist_node_ptr;
1396
1844
 
1397
1845
  typedef hash_key_types_base
1398
1846
  < typename ValueTraits::value_type
@@ -1400,29 +1848,29 @@ struct hashdata_internal
1400
1848
  > hash_types_base;
1401
1849
  typedef typename hash_types_base::key_of_value key_of_value;
1402
1850
 
1403
- static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
1851
+ static const bool store_hash = store_hash_is_true<node_traits>::value;
1404
1852
  static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
1405
1853
  static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
1406
1854
 
1407
1855
  typedef detail::bool_<store_hash> store_hash_t;
1408
1856
 
1409
1857
  typedef detail::transform_iterator
1410
- < typename slist_impl::iterator
1411
- , downcast_node_to_value_t
1412
- < value_traits
1413
- , false> > local_iterator;
1858
+ < siterator
1859
+ , downcast_node_to_value_t<value_traits, false> > local_iterator;
1414
1860
 
1415
1861
  typedef detail::transform_iterator
1416
- < typename slist_impl::iterator
1417
- , downcast_node_to_value_t
1418
- < value_traits
1419
- , true> > const_local_iterator;
1420
- //
1862
+ < siterator
1863
+ , downcast_node_to_value_t<value_traits, true> > const_local_iterator;
1421
1864
 
1422
- template<class BucketTraitsType>
1423
- hashdata_internal( const ValueTraits &val_traits, BOOST_FWD_REF(BucketTraitsType) b_traits
1865
+ typedef detail::bool_<linear_buckets> linear_buckets_t;
1866
+
1867
+ hashdata_internal( const ValueTraits &val_traits, const bucket_traits &b_traits
1424
1868
  , const hasher & h, const key_equal &e)
1425
- : internal_type(val_traits, ::boost::forward<BucketTraitsType>(b_traits), h, e)
1869
+ : internal_type(val_traits, b_traits, h, e)
1870
+ {}
1871
+
1872
+ BOOST_INTRUSIVE_FORCEINLINE hashdata_internal(BOOST_RV_REF(hashdata_internal) other)
1873
+ : internal_type(BOOST_MOVE_BASE(internal_type, other))
1426
1874
  {}
1427
1875
 
1428
1876
  BOOST_INTRUSIVE_FORCEINLINE typename internal_type::size_traits_t priv_split_traits()
@@ -1434,71 +1882,145 @@ struct hashdata_internal
1434
1882
  ~hashdata_internal()
1435
1883
  { this->priv_clear_buckets(); }
1436
1884
 
1885
+ using internal_type::priv_clear_buckets;
1886
+
1437
1887
  void priv_clear_buckets()
1438
1888
  {
1439
- this->internal_type::priv_clear_buckets
1440
- ( this->priv_get_cache()
1441
- , this->internal_type::priv_bucket_count()
1442
- - (this->priv_get_cache()
1443
- - this->internal_type::priv_bucket_pointer()));
1889
+ const std::size_t cache_num = this->priv_get_cache_bucket_num();
1890
+ this->priv_clear_buckets(this->priv_get_cache(), this->priv_usable_bucket_count() - cache_num);
1444
1891
  }
1445
1892
 
1446
1893
  void priv_clear_buckets_and_cache()
1447
1894
  {
1448
1895
  this->priv_clear_buckets();
1449
- this->priv_initialize_cache();
1896
+ this->priv_init_cache();
1450
1897
  }
1451
1898
 
1452
- void priv_initialize_buckets_and_cache()
1899
+ void priv_init_buckets_and_cache()
1453
1900
  {
1454
- this->internal_type::priv_clear_buckets
1455
- ( this->internal_type::priv_bucket_pointer()
1456
- , this->internal_type::priv_bucket_count());
1457
- this->priv_initialize_cache();
1901
+ this->priv_init_buckets(this->priv_bucket_pointer(), this->priv_usable_bucket_count());
1902
+ this->priv_init_cache();
1458
1903
  }
1459
-
1460
- typedef hashtable_iterator<bucket_plus_vtraits_t, false> iterator;
1461
- typedef hashtable_iterator<bucket_plus_vtraits_t, true> const_iterator;
1462
-
1463
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::true_ true_value)
1464
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, true_value); }
1465
-
1466
- static std::size_t priv_stored_hash(slist_node_ptr n, detail::false_ false_value)
1467
- { return bucket_plus_vtraits<ValueTraits, BucketTraits>::priv_stored_hash(n, false_value); }
1904
+
1905
+ typedef typename bucket_plus_vtraits_t::iterator iterator;
1906
+ typedef typename bucket_plus_vtraits_t::const_iterator const_iterator;
1468
1907
 
1469
1908
  //public functions
1470
1909
  BOOST_INTRUSIVE_FORCEINLINE SizeType split_count() const BOOST_NOEXCEPT
1910
+ { return this->priv_split_traits().get_size(); }
1911
+
1912
+ BOOST_INTRUSIVE_FORCEINLINE static SizeType initial_split_from_bucket_count(SizeType bc) BOOST_NOEXCEPT
1913
+ {
1914
+ BOOST_IF_CONSTEXPR(fastmod_buckets) {
1915
+ size_type split;
1916
+ split = static_cast<SizeType>(prime_fmod_size::lower_size_index(bc));
1917
+ //The passed bucket size must be exactly the supported one
1918
+ BOOST_ASSERT(prime_fmod_size::size(split) == bc);
1919
+ return split;
1920
+ }
1921
+ else {
1922
+ BOOST_IF_CONSTEXPR(incremental) {
1923
+ BOOST_ASSERT(0 == (std::size_t(bc) & (std::size_t(bc) - 1u)));
1924
+ return size_type(bc >> 1u);
1925
+ }
1926
+ else{
1927
+ return bc;
1928
+ }
1929
+ }
1930
+ }
1931
+
1932
+ BOOST_INTRUSIVE_FORCEINLINE static SizeType rehash_split_from_bucket_count(SizeType bc) BOOST_NOEXCEPT
1471
1933
  {
1472
- return this->priv_split_traits().get_size();
1934
+ BOOST_IF_CONSTEXPR(fastmod_buckets) {
1935
+ return (initial_split_from_bucket_count)(bc);
1936
+ }
1937
+ else {
1938
+ BOOST_IF_CONSTEXPR(incremental) {
1939
+ BOOST_ASSERT(0 == (std::size_t(bc) & (std::size_t(bc) - 1u)));
1940
+ return bc;
1941
+ }
1942
+ else{
1943
+ return bc;
1944
+ }
1945
+ }
1473
1946
  }
1474
1947
 
1475
- BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value) BOOST_NOEXCEPT
1948
+ BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value) BOOST_NOEXCEPT_IF(!linear_buckets)
1949
+ { return iterator_to(value, linear_buckets_t()); }
1950
+
1951
+ const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT_IF(!linear_buckets)
1952
+ { return iterator_to(value, linear_buckets_t()); }
1953
+
1954
+ iterator iterator_to(reference value, detail::true_) //linear_buckets
1476
1955
  {
1477
- return iterator(bucket_type::s_iterator_to
1478
- (this->priv_value_to_node(value)), &this->get_bucket_value_traits());
1956
+ const std::size_t h = this->priv_stored_or_compute_hash(value, store_hash_t());
1957
+ siterator sit(this->priv_value_to_node_ptr(value));
1958
+ return this->build_iterator(sit, this->priv_hash_to_bucket_ptr(h));
1479
1959
  }
1480
1960
 
1481
- const_iterator iterator_to(const_reference value) const BOOST_NOEXCEPT
1961
+ const_iterator iterator_to(const_reference value, detail::true_) const //linear_buckets
1482
1962
  {
1483
- siterator const sit = bucket_type::s_iterator_to
1484
- ( *pointer_traits<node_ptr>::const_cast_from
1485
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
1963
+ const std::size_t h = this->priv_stored_or_compute_hash(value, store_hash_t());
1964
+ siterator const sit = siterator
1965
+ ( pointer_traits<node_ptr>::const_cast_from(this->priv_value_to_node_ptr(value))
1486
1966
  );
1967
+ return this->build_const_iterator(sit, this->priv_hash_to_bucket_ptr(h));
1968
+ }
1969
+
1970
+ static const bool incremental = 0 != (BoolFlags & hash_bool_flags::incremental_pos);
1971
+ static const bool power_2_buckets = incremental || (0 != (BoolFlags & hash_bool_flags::power_2_buckets_pos));
1972
+ static const bool fastmod_buckets = 0 != (BoolFlags & hash_bool_flags::fastmod_buckets_pos);
1973
+
1974
+ typedef detail::bool_<fastmod_buckets> fastmod_buckets_t;
1975
+
1976
+ BOOST_INTRUSIVE_FORCEINLINE bucket_type &priv_hash_to_bucket(std::size_t hash_value) const
1977
+ { return this->priv_bucket(this->priv_hash_to_nbucket(hash_value)); }
1978
+
1979
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_hash_to_bucket_ptr(std::size_t hash_value) const
1980
+ { return this->priv_bucket_ptr(this->priv_hash_to_nbucket(hash_value)); }
1981
+
1982
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value) const
1983
+ { return (priv_hash_to_nbucket)(hash_value, fastmod_buckets_t()); }
1984
+
1985
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value, detail::true_) const //fastmod_buckets_t
1986
+ {
1987
+ return static_cast<size_type>(hash_to_bucket_split<power_2_buckets, incremental>
1988
+ (hash_value, this->priv_usable_bucket_count(), this->split_count(), detail::true_()));
1989
+ }
1990
+
1991
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_hash_to_nbucket(std::size_t hash_value, detail::false_) const //!fastmod_buckets_t
1992
+ {
1993
+ return static_cast<size_type>(hash_to_bucket_split<power_2_buckets, incremental>
1994
+ (hash_value, this->priv_usable_bucket_count(), this->split_count(), detail::false_()));
1995
+ }
1996
+
1997
+
1998
+ BOOST_INTRUSIVE_FORCEINLINE iterator iterator_to(reference value, detail::false_) BOOST_NOEXCEPT
1999
+ {
2000
+ return iterator( siterator(this->priv_value_to_node_ptr(value))
2001
+ , &this->get_bucket_value_traits());
2002
+ }
2003
+
2004
+ const_iterator iterator_to(const_reference value, detail::false_) const BOOST_NOEXCEPT
2005
+ {
2006
+ siterator const sit = siterator
2007
+ ( pointer_traits<node_ptr>::const_cast_from(this->priv_value_to_node_ptr(value)) );
1487
2008
  return const_iterator(sit, &this->get_bucket_value_traits());
1488
2009
  }
1489
2010
 
2011
+
1490
2012
  static local_iterator s_local_iterator_to(reference value) BOOST_NOEXCEPT
1491
2013
  {
1492
2014
  BOOST_STATIC_ASSERT((!stateful_value_traits));
1493
- siterator sit = bucket_type::s_iterator_to(*value_traits::to_node_ptr(value));
2015
+ siterator sit(value_traits::to_node_ptr(value));
1494
2016
  return local_iterator(sit, const_value_traits_ptr());
1495
2017
  }
1496
2018
 
1497
2019
  static const_local_iterator s_local_iterator_to(const_reference value) BOOST_NOEXCEPT
1498
2020
  {
1499
2021
  BOOST_STATIC_ASSERT((!stateful_value_traits));
1500
- siterator const sit = bucket_type::s_iterator_to
1501
- ( *pointer_traits<node_ptr>::const_cast_from
2022
+ siterator const sit = siterator
2023
+ ( pointer_traits<node_ptr>::const_cast_from
1502
2024
  (value_traits::to_node_ptr(value))
1503
2025
  );
1504
2026
  return const_local_iterator(sit, const_value_traits_ptr());
@@ -1506,52 +2028,58 @@ struct hashdata_internal
1506
2028
 
1507
2029
  local_iterator local_iterator_to(reference value) BOOST_NOEXCEPT
1508
2030
  {
1509
- siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
2031
+ siterator sit(this->priv_value_to_node_ptr(value));
1510
2032
  return local_iterator(sit, this->priv_value_traits_ptr());
1511
2033
  }
1512
2034
 
1513
2035
  const_local_iterator local_iterator_to(const_reference value) const BOOST_NOEXCEPT
1514
2036
  {
1515
- siterator sit = bucket_type::s_iterator_to
1516
- ( *pointer_traits<node_ptr>::const_cast_from
1517
- (pointer_traits<const_node_ptr>::pointer_to(this->priv_value_to_node(value)))
1518
- );
2037
+ siterator sit
2038
+ ( pointer_traits<node_ptr>::const_cast_from(this->priv_value_to_node_ptr(value)) );
1519
2039
  return const_local_iterator(sit, this->priv_value_traits_ptr());
1520
2040
  }
1521
2041
 
1522
2042
  BOOST_INTRUSIVE_FORCEINLINE size_type bucket_count() const BOOST_NOEXCEPT
1523
- {
1524
- const std::size_t bc = this->priv_bucket_count();
1525
- BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(size_type) >= sizeof(std::size_t) || bc <= size_type(-1));
1526
- return static_cast<size_type>(bc);
1527
- }
2043
+ { return size_type(this->priv_usable_bucket_count()); }
1528
2044
 
1529
2045
  BOOST_INTRUSIVE_FORCEINLINE size_type bucket_size(size_type n) const BOOST_NOEXCEPT
1530
- { return this->priv_bucket_pointer()[n].size(); }
2046
+ { return (size_type)this->priv_bucket_size(n); }
1531
2047
 
1532
2048
  BOOST_INTRUSIVE_FORCEINLINE bucket_ptr bucket_pointer() const BOOST_NOEXCEPT
1533
2049
  { return this->priv_bucket_pointer(); }
1534
2050
 
1535
2051
  BOOST_INTRUSIVE_FORCEINLINE local_iterator begin(size_type n) BOOST_NOEXCEPT
1536
- { return local_iterator(this->priv_bucket_pointer()[n].begin(), this->priv_value_traits_ptr()); }
2052
+ { return local_iterator(this->priv_bucket_lbegin(n), this->priv_value_traits_ptr()); }
1537
2053
 
1538
2054
  BOOST_INTRUSIVE_FORCEINLINE const_local_iterator begin(size_type n) const BOOST_NOEXCEPT
1539
2055
  { return this->cbegin(n); }
1540
2056
 
1541
2057
  static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_upper_bucket_count(size_type n) BOOST_NOEXCEPT
1542
2058
  {
1543
- return prime_list_holder<0>::suggested_upper_bucket_count(n);
2059
+ BOOST_IF_CONSTEXPR(fastmod_buckets){
2060
+ std::size_t s = prime_fmod_size::upper_size_index(n);
2061
+ return static_cast<SizeType>(prime_fmod_size::size(s));
2062
+ }
2063
+ else{
2064
+ return prime_list_holder<0>::suggested_upper_bucket_count(n);
2065
+ }
1544
2066
  }
1545
2067
 
1546
2068
  static BOOST_INTRUSIVE_FORCEINLINE size_type suggested_lower_bucket_count(size_type n) BOOST_NOEXCEPT
1547
2069
  {
1548
- return prime_list_holder<0>::suggested_lower_bucket_count(n);
2070
+ BOOST_IF_CONSTEXPR(fastmod_buckets){
2071
+ std::size_t s = prime_fmod_size::lower_size_index(n);
2072
+ return static_cast<SizeType>(prime_fmod_size::size(s));
2073
+ }
2074
+ else{
2075
+ return prime_list_holder<0>::suggested_lower_bucket_count(n);
2076
+ }
1549
2077
  }
1550
2078
 
1551
2079
  const_local_iterator cbegin(size_type n) const BOOST_NOEXCEPT
1552
2080
  {
1553
2081
  return const_local_iterator
1554
- ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].begin()
2082
+ (this->priv_bucket_lbegin(n)
1555
2083
  , this->priv_value_traits_ptr());
1556
2084
  }
1557
2085
 
@@ -1559,7 +2087,7 @@ struct hashdata_internal
1559
2087
  using internal_type::cend;
1560
2088
 
1561
2089
  local_iterator end(size_type n) BOOST_NOEXCEPT
1562
- { return local_iterator(this->priv_bucket_pointer()[n].end(), this->priv_value_traits_ptr()); }
2090
+ { return local_iterator(this->priv_bucket_lend(n), this->priv_value_traits_ptr()); }
1563
2091
 
1564
2092
  BOOST_INTRUSIVE_FORCEINLINE const_local_iterator end(size_type n) const BOOST_NOEXCEPT
1565
2093
  { return this->cend(n); }
@@ -1567,20 +2095,28 @@ struct hashdata_internal
1567
2095
  const_local_iterator cend(size_type n) const BOOST_NOEXCEPT
1568
2096
  {
1569
2097
  return const_local_iterator
1570
- ( pointer_traits<bucket_ptr>::const_cast_from(this->priv_bucket_pointer())[n].end()
2098
+ ( this->priv_bucket_lend(n)
1571
2099
  , this->priv_value_traits_ptr());
1572
2100
  }
1573
2101
 
1574
2102
  //Public functions for hashtable_impl
1575
2103
 
1576
2104
  BOOST_INTRUSIVE_FORCEINLINE iterator begin() BOOST_NOEXCEPT
1577
- { return iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
2105
+ {
2106
+ bucket_ptr p;
2107
+ siterator s = this->priv_begin(p);
2108
+ return this->build_iterator(s, p);
2109
+ }
1578
2110
 
1579
2111
  BOOST_INTRUSIVE_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT
1580
2112
  { return this->cbegin(); }
1581
2113
 
1582
2114
  BOOST_INTRUSIVE_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT
1583
- { return const_iterator(this->priv_begin(), &this->get_bucket_value_traits()); }
2115
+ {
2116
+ bucket_ptr p;
2117
+ siterator s = this->priv_begin(p);
2118
+ return this->build_const_iterator(s, p);
2119
+ }
1584
2120
 
1585
2121
  BOOST_INTRUSIVE_FORCEINLINE hasher hash_function() const
1586
2122
  { return this->priv_hasher(); }
@@ -1589,6 +2125,23 @@ struct hashdata_internal
1589
2125
  { return this->priv_equal(); }
1590
2126
  };
1591
2127
 
2128
+ template< class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash
2129
+ , class VoidOrKeyEqual, class BucketTraits, class SizeType
2130
+ , std::size_t BoolFlags>
2131
+ struct get_hashtable_size_wrapper_internal
2132
+ {
2133
+ typedef hashtable_size_wrapper
2134
+ < hashdata_internal
2135
+ < ValueTraits
2136
+ , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
2137
+ , BucketTraits, SizeType
2138
+ , BoolFlags & ~(hash_bool_flags::constant_time_size_pos) //1
2139
+ >
2140
+ , SizeType
2141
+ , (BoolFlags& hash_bool_flags::constant_time_size_pos) != 0
2142
+ > type;
2143
+ };
2144
+
1592
2145
  /// @endcond
1593
2146
 
1594
2147
  //! The class template hashtable is an intrusive hash table container, that
@@ -1633,27 +2186,13 @@ template<class T, class ...Options>
1633
2186
  template<class ValueTraits, class VoidOrKeyOfValue, class VoidOrKeyHash, class VoidOrKeyEqual, class BucketTraits, class SizeType, std::size_t BoolFlags>
1634
2187
  #endif
1635
2188
  class hashtable_impl
1636
- : private hashtable_size_traits_wrapper
1637
- < hashdata_internal
1638
- < ValueTraits
1639
- , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
1640
- , BucketTraits, SizeType
1641
- , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
1642
- >
1643
- , SizeType
1644
- , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
1645
- >
2189
+ : private get_hashtable_size_wrapper_internal
2190
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::type
1646
2191
  {
1647
- typedef hashtable_size_traits_wrapper
1648
- < hashdata_internal
1649
- < ValueTraits
1650
- , VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual
1651
- , BucketTraits, SizeType
1652
- , BoolFlags & (hash_bool_flags::incremental_pos | hash_bool_flags::cache_begin_pos) //1
1653
- >
1654
- , SizeType
1655
- , (BoolFlags & hash_bool_flags::constant_time_size_pos) != 0
1656
- > internal_type;
2192
+ static const bool linear_buckets_flag = (BoolFlags & hash_bool_flags::linear_buckets_pos) != 0;
2193
+ typedef typename get_hashtable_size_wrapper_internal
2194
+ <ValueTraits, VoidOrKeyOfValue, VoidOrKeyHash, VoidOrKeyEqual, BucketTraits, SizeType, BoolFlags>::type
2195
+ internal_type;
1657
2196
  typedef typename internal_type::size_traits size_traits;
1658
2197
  typedef hash_key_types_base
1659
2198
  < typename ValueTraits::value_type
@@ -1665,10 +2204,14 @@ class hashtable_impl
1665
2204
  /// @cond
1666
2205
  typedef BucketTraits bucket_traits;
1667
2206
 
1668
- typedef typename internal_type::slist_impl slist_impl;
1669
- typedef bucket_plus_vtraits<ValueTraits, BucketTraits> bucket_plus_vtraits_t;
2207
+ typedef bucket_plus_vtraits
2208
+ <ValueTraits, BucketTraits, linear_buckets_flag> bucket_plus_vtraits_t;
1670
2209
  typedef typename bucket_plus_vtraits_t::const_value_traits_ptr const_value_traits_ptr;
1671
2210
 
2211
+ typedef detail::bool_<linear_buckets_flag> linear_buckets_t;
2212
+
2213
+ typedef typename internal_type::siterator siterator;
2214
+ typedef typename internal_type::const_siterator const_siterator;
1672
2215
  using internal_type::begin;
1673
2216
  using internal_type::cbegin;
1674
2217
  using internal_type::end;
@@ -1698,10 +2241,8 @@ class hashtable_impl
1698
2241
  typedef SizeType size_type;
1699
2242
  typedef typename internal_type::key_equal key_equal;
1700
2243
  typedef typename internal_type::hasher hasher;
1701
- typedef bucket_impl<slist_impl> bucket_type;
2244
+ typedef typename internal_type::bucket_type bucket_type;
1702
2245
  typedef typename internal_type::bucket_ptr bucket_ptr;
1703
- typedef typename slist_impl::iterator siterator;
1704
- typedef typename slist_impl::const_iterator const_siterator;
1705
2246
  typedef typename internal_type::iterator iterator;
1706
2247
  typedef typename internal_type::const_iterator const_iterator;
1707
2248
  typedef typename internal_type::local_iterator local_iterator;
@@ -1718,7 +2259,7 @@ class hashtable_impl
1718
2259
  <node_ptr>::reference node_reference;
1719
2260
  typedef typename pointer_traits
1720
2261
  <const_node_ptr>::reference const_node_reference;
1721
- typedef typename slist_impl::node_algorithms node_algorithms;
2262
+ typedef typename internal_type::slist_node_algorithms slist_node_algorithms;
1722
2263
 
1723
2264
  static const bool stateful_value_traits = internal_type::stateful_value_traits;
1724
2265
  static const bool store_hash = internal_type::store_hash;
@@ -1729,9 +2270,10 @@ class hashtable_impl
1729
2270
  static const bool compare_hash = 0 != (BoolFlags & hash_bool_flags::compare_hash_pos);
1730
2271
  static const bool incremental = 0 != (BoolFlags & hash_bool_flags::incremental_pos);
1731
2272
  static const bool power_2_buckets = incremental || (0 != (BoolFlags & hash_bool_flags::power_2_buckets_pos));
1732
-
1733
- static const bool optimize_multikey
1734
- = detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
2273
+ static const bool optimize_multikey = optimize_multikey_is_true<node_traits>::value && !unique_keys;
2274
+ static const bool linear_buckets = linear_buckets_flag;
2275
+ static const bool fastmod_buckets = 0 != (BoolFlags & hash_bool_flags::fastmod_buckets_pos);
2276
+ static const std::size_t bucket_overhead = internal_type::bucket_overhead;
1735
2277
 
1736
2278
  /// @cond
1737
2279
  static const bool is_multikey = !unique_keys;
@@ -1741,7 +2283,11 @@ class hashtable_impl
1741
2283
  //See documentation for more explanations
1742
2284
  BOOST_STATIC_ASSERT((!compare_hash || store_hash));
1743
2285
 
1744
- typedef typename slist_impl::node_ptr slist_node_ptr;
2286
+ //Configuration error: fasmod_buckets<> can't be specified with incremental<> or power_2_buckets<>
2287
+ //See documentation for more explanations
2288
+ BOOST_STATIC_ASSERT(!(fastmod_buckets && power_2_buckets));
2289
+
2290
+ typedef typename internal_type::slist_node_ptr slist_node_ptr;
1745
2291
  typedef typename pointer_traits
1746
2292
  <slist_node_ptr>::template rebind_pointer
1747
2293
  < void >::type void_pointer;
@@ -1753,9 +2299,11 @@ class hashtable_impl
1753
2299
  typedef detail::bool_<optimize_multikey> optimize_multikey_t;
1754
2300
  typedef detail::bool_<cache_begin> cache_begin_t;
1755
2301
  typedef detail::bool_<power_2_buckets> power_2_buckets_t;
2302
+ typedef detail::bool_<fastmod_buckets> fastmod_buckets_t;
2303
+ typedef detail::bool_<compare_hash> compare_hash_t;
1756
2304
  typedef typename internal_type::split_traits split_traits;
1757
- typedef detail::group_functions<node_traits> group_functions_t;
1758
- typedef detail::node_functions<node_traits> node_functions_t;
2305
+ typedef group_functions<node_traits> group_functions_t;
2306
+ typedef node_functions<node_traits> node_functions_t;
1759
2307
 
1760
2308
  private:
1761
2309
  //noncopyable, movable
@@ -1768,27 +2316,24 @@ class hashtable_impl
1768
2316
  //Cache begin is incompatible with auto-unlink hooks!
1769
2317
  BOOST_STATIC_ASSERT(!(cache_begin && ((int)value_traits::link_mode == (int)auto_unlink)));
1770
2318
 
1771
- template<class Disposer>
1772
- struct typeof_node_disposer
1773
- {
1774
- typedef node_cast_adaptor
1775
- < detail::node_disposer< Disposer, value_traits, CircularSListAlgorithms>
1776
- , slist_node_ptr, node_ptr > type;
1777
- };
1778
-
1779
- template<class Disposer>
1780
- typename typeof_node_disposer<Disposer>::type
1781
- make_node_disposer(const Disposer &disposer) const
1782
- {
1783
- typedef typename typeof_node_disposer<Disposer>::type return_t;
1784
- return return_t(disposer, &this->priv_value_traits());
1785
- }
1786
2319
 
1787
2320
  /// @endcond
1788
-
2321
+
1789
2322
  public:
1790
- typedef detail::insert_commit_data_impl insert_commit_data;
2323
+ typedef insert_commit_data_impl<store_hash> insert_commit_data;
1791
2324
 
2325
+ void default_init_actions()
2326
+ {
2327
+ this->priv_set_sentinel_bucket();
2328
+ this->priv_init_buckets_and_cache();
2329
+ this->priv_size_traits().set_size(size_type(0));
2330
+ size_type bucket_sz = this->bucket_count();
2331
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
2332
+ //Check power of two bucket array if the option is activated
2333
+ BOOST_INTRUSIVE_INVARIANT_ASSERT
2334
+ (!power_2_buckets || (0 == (bucket_sz & (bucket_sz - 1))));
2335
+ this->priv_split_traits().set_size(this->initial_split_from_bucket_count(bucket_sz));
2336
+ }
1792
2337
 
1793
2338
  public:
1794
2339
 
@@ -1810,16 +2355,7 @@ class hashtable_impl
1810
2355
  , const key_equal &equal_func = key_equal()
1811
2356
  , const value_traits &v_traits = value_traits())
1812
2357
  : internal_type(v_traits, b_traits, hash_func, equal_func)
1813
- {
1814
- this->priv_initialize_buckets_and_cache();
1815
- this->priv_size_traits().set_size(size_type(0));
1816
- size_type bucket_sz = this->bucket_count();
1817
- BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
1818
- //Check power of two bucket array if the option is activated
1819
- BOOST_INTRUSIVE_INVARIANT_ASSERT
1820
- (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
1821
- this->priv_split_traits().set_size(bucket_sz>>1);
1822
- }
2358
+ { this->default_init_actions(); }
1823
2359
 
1824
2360
  //! <b>Requires</b>: buckets must not be being used by any other resource
1825
2361
  //! and dereferencing iterator must yield an lvalue of type value_type.
@@ -1844,14 +2380,8 @@ class hashtable_impl
1844
2380
  , const value_traits &v_traits = value_traits())
1845
2381
  : internal_type(v_traits, b_traits, hash_func, equal_func)
1846
2382
  {
1847
- this->priv_initialize_buckets_and_cache();
1848
- this->priv_size_traits().set_size(size_type(0));
1849
- size_type bucket_sz = this->bucket_count();
1850
- BOOST_INTRUSIVE_INVARIANT_ASSERT(bucket_sz != 0);
1851
- //Check power of two bucket array if the option is activated
1852
- BOOST_INTRUSIVE_INVARIANT_ASSERT
1853
- (!power_2_buckets || (0 == (bucket_sz & (bucket_sz-1))));
1854
- this->priv_split_traits().set_size(bucket_sz>>1);
2383
+ this->default_init_actions();
2384
+
1855
2385
  //Now insert
1856
2386
  if(unique)
1857
2387
  this->insert_unique(b, e);
@@ -1869,17 +2399,13 @@ class hashtable_impl
1869
2399
  //! move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
1870
2400
  //! or the move constructor of value traits, bucket traits, hasher or comparison throws.
1871
2401
  hashtable_impl(BOOST_RV_REF(hashtable_impl) x)
1872
- : internal_type( ::boost::move(x.priv_value_traits())
1873
- , ::boost::move(x.priv_bucket_traits())
1874
- , ::boost::move(x.priv_hasher())
1875
- , ::boost::move(x.priv_equal())
1876
- )
2402
+ : internal_type(BOOST_MOVE_BASE(internal_type, x))
1877
2403
  {
1878
2404
  this->priv_swap_cache(x);
1879
- x.priv_initialize_cache();
2405
+ x.priv_init_cache();
1880
2406
  this->priv_size_traits().set_size(x.priv_size_traits().get_size());
1881
2407
  x.priv_size_traits().set_size(size_type(0));
1882
- this->priv_split_traits().set_size(x.priv_split_traits().get_size());
2408
+ this->priv_split_traits().set_size(x.split_count());
1883
2409
  x.priv_split_traits().set_size(size_type(0));
1884
2410
  }
1885
2411
 
@@ -1888,7 +2414,6 @@ class hashtable_impl
1888
2414
  hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x)
1889
2415
  { this->swap(x); return *this; }
1890
2416
 
1891
- #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1892
2417
  //! <b>Effects</b>: Detaches all elements from this. The objects in the unordered_set
1893
2418
  //! are not deleted (i.e. no destructors are called).
1894
2419
  //!
@@ -1896,8 +2421,10 @@ class hashtable_impl
1896
2421
  //! it's a safe-mode or auto-unlink value. Otherwise constant.
1897
2422
  //!
1898
2423
  //! <b>Throws</b>: Nothing.
1899
- ~hashtable_impl();
2424
+ ~hashtable_impl()
2425
+ {}
1900
2426
 
2427
+ #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
1901
2428
  //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
1902
2429
  //!
1903
2430
  //! <b>Complexity</b>: Amortized constant time.
@@ -1980,7 +2507,7 @@ class hashtable_impl
1980
2507
  size_type bucket_cnt = this->bucket_count();
1981
2508
  const bucket_type *b = boost::movelib::to_raw_pointer(this->priv_bucket_pointer());
1982
2509
  for (size_type n = 0; n < bucket_cnt; ++n, ++b){
1983
- if(!b->empty()){
2510
+ if(!slist_node_algorithms::is_empty(b->get_node_ptr())){
1984
2511
  return false;
1985
2512
  }
1986
2513
  }
@@ -1999,13 +2526,14 @@ class hashtable_impl
1999
2526
  BOOST_IF_CONSTEXPR(constant_time_size)
2000
2527
  return this->priv_size_traits().get_size();
2001
2528
  else{
2002
- size_type len = 0;
2003
- size_type bucket_cnt = this->bucket_count();
2529
+ std::size_t len = 0;
2530
+ std::size_t bucket_cnt = this->bucket_count();
2004
2531
  const bucket_type *b = boost::movelib::to_raw_pointer(this->priv_bucket_pointer());
2005
- for (size_type n = 0; n < bucket_cnt; ++n, ++b){
2006
- len += b->size();
2532
+ for (std::size_t n = 0; n < bucket_cnt; ++n, ++b){
2533
+ len += slist_node_algorithms::count(b->get_node_ptr()) - 1u;
2007
2534
  }
2008
- return len;
2535
+ BOOST_INTRUSIVE_INVARIANT_ASSERT((len <= SizeType(-1)));
2536
+ return size_type(len);
2009
2537
  }
2010
2538
  }
2011
2539
 
@@ -2097,7 +2625,7 @@ class hashtable_impl
2097
2625
  siterator prev;
2098
2626
  siterator const it = this->priv_find
2099
2627
  (key_of_value()(value), this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
2100
- bool const next_is_in_group = optimize_multikey && it != this->priv_invalid_local_it();
2628
+ bool const next_is_in_group = optimize_multikey && it != this->priv_end_sit();
2101
2629
  return this->priv_insert_equal_after_find(value, bucket_num, hash_value, prev, next_is_in_group);
2102
2630
  }
2103
2631
 
@@ -2207,12 +2735,15 @@ class hashtable_impl
2207
2735
  , KeyEqual equal_func
2208
2736
  , insert_commit_data &commit_data)
2209
2737
  {
2210
- size_type bucket_num;
2211
- siterator prev;
2212
- siterator const pos = this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
2213
- return std::pair<iterator, bool>
2214
- ( iterator(pos, &this->get_bucket_value_traits())
2215
- , pos == this->priv_invalid_local_it());
2738
+ const std::size_t h = hash_func(key);
2739
+ const std::size_t bn = this->priv_hash_to_nbucket(h);
2740
+
2741
+ commit_data.bucket_idx = bn;
2742
+ commit_data.set_hash(h);
2743
+
2744
+ bucket_ptr bp = this->priv_bucket_ptr(bn);
2745
+ siterator const s = this->priv_find_in_bucket(*bp, key, equal_func, h);
2746
+ return std::pair<iterator, bool>(this->build_iterator(s, bp), s == this->priv_end_sit());
2216
2747
  }
2217
2748
 
2218
2749
  //! <b>Effects</b>: Checks if a value can be inserted in the unordered_set, using
@@ -2267,15 +2798,15 @@ class hashtable_impl
2267
2798
  //! After a successful rehashing insert_commit_data remains valid.
2268
2799
  iterator insert_unique_commit(reference value, const insert_commit_data &commit_data) BOOST_NOEXCEPT
2269
2800
  {
2270
- size_type bucket_num = this->priv_hash_to_bucket(commit_data.hash);
2271
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
2272
2801
  this->priv_size_traits().increment();
2273
- node_ptr const n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
2274
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
2275
- node_functions_t::store_hash(n, commit_data.hash, store_hash_t());
2276
- this->priv_insertion_update_cache(bucket_num);
2802
+ node_ptr const n = this->priv_value_to_node_ptr(value);
2803
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || slist_node_algorithms::unique(n));
2804
+ node_functions_t::store_hash(n, commit_data.get_hash(), store_hash_t());
2805
+ this->priv_insertion_update_cache(static_cast<size_type>(commit_data.bucket_idx));
2277
2806
  group_functions_t::insert_in_group(n, n, optimize_multikey_t());
2278
- return iterator(b.insert_after(b.before_begin(), *n), &this->get_bucket_value_traits());
2807
+ bucket_type& b = this->priv_bucket(commit_data.bucket_idx);
2808
+ slist_node_algorithms::link_after(b.get_node_ptr(), n);
2809
+ return this->build_iterator(siterator(n), this->to_ptr(b));
2279
2810
  }
2280
2811
 
2281
2812
  //! <b>Effects</b>: Erases the element pointed to by i.
@@ -2357,11 +2888,10 @@ class hashtable_impl
2357
2888
  erase_and_dispose(const_iterator i, Disposer disposer) BOOST_NOEXCEPT
2358
2889
  {
2359
2890
  //Get the bucket number and local iterator for both iterators
2360
- siterator const first_local_it(i.slist_it());
2361
- size_type const first_bucket_num = this->priv_get_bucket_num(first_local_it);
2362
- this->priv_erase_node(this->priv_bucket_pointer()[first_bucket_num], first_local_it, make_node_disposer(disposer), optimize_multikey_t());
2891
+ const bucket_ptr bp = this->priv_get_bucket_ptr(i);
2892
+ this->priv_erase_node(*bp, i.slist_it(), this->make_node_disposer(disposer), optimize_multikey_t());
2363
2893
  this->priv_size_traits().decrement();
2364
- this->priv_erasure_update_cache_range(first_bucket_num, first_bucket_num);
2894
+ this->priv_erasure_update_cache(bp);
2365
2895
  }
2366
2896
 
2367
2897
  //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -2381,29 +2911,27 @@ class hashtable_impl
2381
2911
  {
2382
2912
  if(b != e){
2383
2913
  //Get the bucket number and local iterator for both iterators
2384
- siterator first_local_it(b.slist_it());
2385
- size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
2914
+ size_type first_bucket_num = this->priv_get_bucket_num(b);
2386
2915
 
2387
- const bucket_ptr buck_ptr = this->priv_bucket_pointer();
2388
2916
  siterator before_first_local_it
2389
- = this->priv_get_previous(buck_ptr[first_bucket_num], first_local_it);
2917
+ = this->priv_get_previous(this->priv_bucket(first_bucket_num), b.slist_it(), optimize_multikey_t());
2390
2918
  size_type last_bucket_num;
2391
2919
  siterator last_local_it;
2392
2920
 
2393
2921
  //For the end iterator, we will assign the end iterator
2394
2922
  //of the last bucket
2395
2923
  if(e == this->end()){
2396
- last_bucket_num = this->bucket_count() - 1;
2397
- last_local_it = buck_ptr[last_bucket_num].end();
2924
+ last_bucket_num = size_type(this->bucket_count() - 1u);
2925
+ last_local_it = this->sit_end(this->priv_bucket(last_bucket_num));
2398
2926
  }
2399
2927
  else{
2400
2928
  last_local_it = e.slist_it();
2401
- last_bucket_num = this->priv_get_bucket_num(last_local_it);
2929
+ last_bucket_num = this->priv_get_bucket_num(e);
2402
2930
  }
2403
- size_type const num_erased = this->priv_erase_node_range
2931
+ size_type const num_erased = (size_type)this->priv_erase_node_range
2404
2932
  ( before_first_local_it, first_bucket_num, last_local_it, last_bucket_num
2405
- , make_node_disposer(disposer), optimize_multikey_t());
2406
- this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
2933
+ , this->make_node_disposer(disposer), optimize_multikey_t());
2934
+ this->priv_size_traits().set_size(size_type(this->priv_size_traits().get_size()-num_erased));
2407
2935
  this->priv_erasure_update_cache_range(first_bucket_num, last_bucket_num);
2408
2936
  }
2409
2937
  }
@@ -2450,30 +2978,34 @@ class hashtable_impl
2450
2978
  std::size_t h;
2451
2979
  siterator prev;
2452
2980
  siterator it = this->priv_find(key, hash_func, equal_func, bucket_num, h, prev);
2453
- bool const success = it != this->priv_invalid_local_it();
2981
+ bool const success = it != this->priv_end_sit();
2454
2982
 
2455
- size_type cnt(0);
2983
+ std::size_t cnt(0);
2456
2984
  if(success){
2457
2985
  if(optimize_multikey){
2986
+ siterator past_last_in_group = it;
2987
+ (priv_go_to_last_in_group)(past_last_in_group, optimize_multikey_t());
2988
+ ++past_last_in_group;
2458
2989
  cnt = this->priv_erase_from_single_bucket
2459
- (this->priv_bucket_pointer()[bucket_num], prev, ++(priv_last_in_group)(it), make_node_disposer(disposer), optimize_multikey_t());
2990
+ ( this->priv_bucket(bucket_num), prev
2991
+ , past_last_in_group
2992
+ , this->make_node_disposer(disposer), optimize_multikey_t());
2460
2993
  }
2461
2994
  else{
2462
- bucket_type &b = this->priv_bucket_pointer()[bucket_num];
2463
- siterator const end_sit = b.end();
2995
+ siterator const end_sit = this->priv_bucket_lend(bucket_num);
2464
2996
  do{
2465
2997
  ++cnt;
2466
2998
  ++it;
2467
2999
  }while(it != end_sit &&
2468
- this->priv_is_value_equal_to_key
2469
- (this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func));
2470
- bucket_type::s_erase_after_and_dispose(prev, it, make_node_disposer(disposer));
3000
+ this->priv_is_value_equal_to_key
3001
+ (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t()));
3002
+ slist_node_algorithms::unlink_after_and_dispose(prev.pointed_node(), it.pointed_node(), this->make_node_disposer(disposer));
2471
3003
  }
2472
- this->priv_size_traits().set_size(this->priv_size_traits().get_size()-cnt);
3004
+ this->priv_size_traits().set_size(size_type(this->priv_size_traits().get_size()-cnt));
2473
3005
  this->priv_erasure_update_cache();
2474
3006
  }
2475
3007
 
2476
- return cnt;
3008
+ return static_cast<size_type>(cnt);
2477
3009
  }
2478
3010
 
2479
3011
  //! <b>Effects</b>: Erases all of the elements.
@@ -2508,13 +3040,14 @@ class hashtable_impl
2508
3040
  if(!constant_time_size || !this->empty()){
2509
3041
  size_type num_buckets = this->bucket_count();
2510
3042
  bucket_ptr b = this->priv_bucket_pointer();
2511
- typename typeof_node_disposer<Disposer>::type d(disposer, &this->priv_value_traits());
2512
- for(; num_buckets--; ++b){
2513
- b->clear_and_dispose(d);
3043
+ typename internal_type::template typeof_node_disposer<Disposer>::type d(disposer, &this->priv_value_traits());
3044
+ for(; num_buckets; ++b){
3045
+ --num_buckets;
3046
+ slist_node_algorithms::detach_and_dispose(b->get_node_ptr(), d);
2514
3047
  }
2515
3048
  this->priv_size_traits().set_size(size_type(0));
2516
3049
  }
2517
- this->priv_initialize_cache();
3050
+ this->priv_init_cache();
2518
3051
  }
2519
3052
 
2520
3053
  //! <b>Effects</b>: Returns the number of contained elements with the given value
@@ -2578,11 +3111,10 @@ class hashtable_impl
2578
3111
  template<class KeyType, class KeyHasher, class KeyEqual>
2579
3112
  iterator find(const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
2580
3113
  {
2581
- size_type bucket_n;
2582
- std::size_t hash;
2583
- siterator prev;
2584
- return iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev)
2585
- , &this->get_bucket_value_traits());
3114
+ std::size_t h = hash_func(key);
3115
+ bucket_ptr bp = this->priv_hash_to_bucket_ptr(h);
3116
+ siterator s = this->priv_find_in_bucket(*bp, key, equal_func, h);
3117
+ return this->build_iterator(s, bp);
2586
3118
  }
2587
3119
 
2588
3120
  //! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -2617,11 +3149,10 @@ class hashtable_impl
2617
3149
  const_iterator find
2618
3150
  (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
2619
3151
  {
2620
- size_type bucket_n;
2621
- std::size_t hash_value;
2622
- siterator prev;
2623
- return const_iterator( this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev)
2624
- , &this->get_bucket_value_traits());
3152
+ std::size_t h = hash_func(key);
3153
+ bucket_ptr bp = this->priv_hash_to_bucket_ptr(h);
3154
+ siterator s = this->priv_find_in_bucket(*bp, key, equal_func, h);
3155
+ return this->build_const_iterator(s, bp);
2625
3156
  }
2626
3157
 
2627
3158
  //! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2658,11 +3189,11 @@ class hashtable_impl
2658
3189
  std::pair<iterator,iterator> equal_range
2659
3190
  (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func)
2660
3191
  {
2661
- std::pair<siterator, siterator> ret =
3192
+ priv_equal_range_result ret =
2662
3193
  this->priv_equal_range(key, hash_func, equal_func);
2663
3194
  return std::pair<iterator, iterator>
2664
- ( iterator(ret.first, &this->get_bucket_value_traits())
2665
- , iterator(ret.second, &this->get_bucket_value_traits()));
3195
+ ( this->build_iterator(ret.first, ret.bucket_first)
3196
+ , this->build_iterator(ret.second, ret.bucket_second));
2666
3197
  }
2667
3198
 
2668
3199
  //! <b>Effects</b>: Returns a range containing all elements with values equivalent
@@ -2700,11 +3231,11 @@ class hashtable_impl
2700
3231
  std::pair<const_iterator,const_iterator> equal_range
2701
3232
  (const KeyType &key, KeyHasher hash_func, KeyEqual equal_func) const
2702
3233
  {
2703
- std::pair<siterator, siterator> ret =
3234
+ priv_equal_range_result ret =
2704
3235
  this->priv_equal_range(key, hash_func, equal_func);
2705
3236
  return std::pair<const_iterator, const_iterator>
2706
- ( const_iterator(ret.first, &this->get_bucket_value_traits())
2707
- , const_iterator(ret.second, &this->get_bucket_value_traits()));
3237
+ ( this->build_const_iterator(ret.first, ret.bucket_first)
3238
+ , this->build_const_iterator(ret.second, ret.bucket_second));
2708
3239
  }
2709
3240
 
2710
3241
  #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
@@ -2824,7 +3355,7 @@ class hashtable_impl
2824
3355
  //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
2825
3356
  template<class KeyType, class KeyHasher>
2826
3357
  BOOST_INTRUSIVE_FORCEINLINE size_type bucket(const KeyType& k, KeyHasher hash_func) const
2827
- { return this->priv_hash_to_bucket(hash_func(k)); }
3358
+ { return this->priv_hash_to_nbucket(hash_func(k)); }
2828
3359
 
2829
3360
  #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
2830
3361
  //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
@@ -2942,7 +3473,7 @@ class hashtable_impl
2942
3473
  //!
2943
3474
  //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
2944
3475
  BOOST_INTRUSIVE_FORCEINLINE void rehash(const bucket_traits &new_bucket_traits)
2945
- { this->rehash_impl(new_bucket_traits, false); }
3476
+ { this->priv_rehash_impl(new_bucket_traits, false); }
2946
3477
 
2947
3478
  //! <b>Note</b>: This function is used when keys from inserted elements are changed
2948
3479
  //! (e.g. a language change when key is a string) but uniqueness and hash properties are
@@ -2965,7 +3496,7 @@ class hashtable_impl
2965
3496
  //!
2966
3497
  //! <b>Throws</b>: If the hasher functor throws. Basic guarantee.
2967
3498
  BOOST_INTRUSIVE_FORCEINLINE void full_rehash()
2968
- { this->rehash_impl(this->priv_bucket_traits(), true); }
3499
+ { this->priv_rehash_impl(this->priv_bucket_traits(), true); }
2969
3500
 
2970
3501
  //! <b>Requires</b>:
2971
3502
  //!
@@ -2980,46 +3511,48 @@ class hashtable_impl
2980
3511
  {
2981
3512
  //This function is only available for containers with incremental hashing
2982
3513
  BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
2983
- const size_type split_idx = this->priv_split_traits().get_size();
2984
- const size_type bucket_cnt = this->bucket_count();
2985
- const bucket_ptr buck_ptr = this->priv_bucket_pointer();
3514
+ const std::size_t split_idx = this->split_count();
3515
+ const std::size_t bucket_cnt = this->bucket_count();
2986
3516
  bool ret = false;
2987
3517
 
2988
3518
  if(grow){
2989
3519
  //Test if the split variable can be changed
2990
3520
  if((ret = split_idx < bucket_cnt)){
2991
- const size_type bucket_to_rehash = split_idx - bucket_cnt/2;
2992
- bucket_type &old_bucket = buck_ptr[bucket_to_rehash];
3521
+ const std::size_t bucket_to_rehash = split_idx - bucket_cnt/2u;
3522
+ bucket_type &old_bucket = this->priv_bucket(bucket_to_rehash);
2993
3523
  this->priv_split_traits().increment();
2994
3524
 
2995
3525
  //Anti-exception stuff: if an exception is thrown while
2996
3526
  //moving elements from old_bucket to the target bucket, all moved
2997
3527
  //elements are moved back to the original one.
2998
- detail::incremental_rehash_rollback<bucket_type, split_traits> rollback
2999
- ( buck_ptr[split_idx], old_bucket, this->priv_split_traits());
3000
- for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
3001
- ; i != end_sit; i = before_i, ++i){
3002
- const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
3528
+ incremental_rehash_rollback<bucket_type, split_traits, slist_node_algorithms> rollback
3529
+ ( this->priv_bucket(split_idx), old_bucket, this->priv_split_traits());
3530
+ siterator before_i(old_bucket.get_node_ptr());
3531
+ siterator i(before_i); ++i;
3532
+ siterator end_sit = linear_buckets ? siterator() : before_i;
3533
+ for( ; i != end_sit; i = before_i, ++i){
3534
+ const value_type &v = this->priv_value_from_siterator(i);
3003
3535
  const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
3004
- const size_type new_n = this->priv_hash_to_bucket(hash_value);
3005
- siterator const last = (priv_last_in_group)(i);
3536
+ const std::size_t new_n = this->priv_hash_to_nbucket(hash_value);
3537
+ siterator last = i;
3538
+ (priv_go_to_last_in_group)(last, optimize_multikey_t());
3006
3539
  if(new_n == bucket_to_rehash){
3007
3540
  before_i = last;
3008
3541
  }
3009
3542
  else{
3010
- bucket_type &new_b = buck_ptr[new_n];
3011
- new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
3543
+ bucket_type &new_b = this->priv_bucket(new_n);
3544
+ slist_node_algorithms::transfer_after(new_b.get_node_ptr(), before_i.pointed_node(), last.pointed_node());
3012
3545
  }
3013
3546
  }
3014
3547
  rollback.release();
3015
3548
  this->priv_erasure_update_cache();
3016
3549
  }
3017
3550
  }
3018
- else if((ret = split_idx > bucket_cnt/2)){ //!grow
3019
- const size_type target_bucket_num = split_idx - 1 - bucket_cnt/2;
3020
- bucket_type &target_bucket = buck_ptr[target_bucket_num];
3021
- bucket_type &source_bucket = buck_ptr[split_idx-1];
3022
- target_bucket.splice_after(target_bucket.cbefore_begin(), source_bucket);
3551
+ else if((ret = split_idx > bucket_cnt/2u)){ //!grow
3552
+ const std::size_t target_bucket_num = split_idx - 1u - bucket_cnt/2u;
3553
+ bucket_type &target_bucket = this->priv_bucket(target_bucket_num);
3554
+ bucket_type &source_bucket = this->priv_bucket(split_idx-1u);
3555
+ slist_node_algorithms::transfer_after(target_bucket.get_node_ptr(), source_bucket.get_node_ptr());
3023
3556
  this->priv_split_traits().decrement();
3024
3557
  this->priv_insertion_update_cache(target_bucket_num);
3025
3558
  }
@@ -3043,36 +3576,46 @@ class hashtable_impl
3043
3576
  {
3044
3577
  //This function is only available for containers with incremental hashing
3045
3578
  BOOST_STATIC_ASSERT(( incremental && power_2_buckets ));
3046
- size_type const new_bucket_traits_size = new_bucket_traits.bucket_count();
3047
- size_type const cur_bucket_traits = this->bucket_count();
3579
+ const bucket_ptr new_buckets = new_bucket_traits.bucket_begin();
3580
+ const size_type new_bucket_count_stdszt = static_cast<SizeType>(new_bucket_traits.bucket_count() - bucket_overhead);
3581
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(size_type) >= sizeof(std::size_t) || new_bucket_count_stdszt <= size_type(-1));
3582
+ size_type new_bucket_count = static_cast<size_type>(new_bucket_count_stdszt);
3583
+ const size_type old_bucket_count = static_cast<size_type>(this->priv_usable_bucket_count());
3048
3584
  const size_type split_idx = this->split_count();
3049
3585
 
3050
3586
  //Test new bucket size is consistent with internal bucket size and split count
3051
- if(new_bucket_traits_size/2 == cur_bucket_traits){
3052
- if(!(split_idx >= cur_bucket_traits))
3587
+ if(new_bucket_count/2 == old_bucket_count){
3588
+ if(!(split_idx >= old_bucket_count))
3053
3589
  return false;
3054
3590
  }
3055
- else if(new_bucket_traits_size == cur_bucket_traits/2){
3056
- if(!(split_idx <= new_bucket_traits_size))
3591
+ else if(new_bucket_count == old_bucket_count/2){
3592
+ if(!(split_idx <= new_bucket_count))
3057
3593
  return false;
3058
3594
  }
3059
3595
  else{
3060
3596
  return false;
3061
3597
  }
3062
3598
 
3063
- const size_type ini_n = this->priv_get_cache_bucket_num();
3599
+ const size_type ini_n = (size_type)this->priv_get_cache_bucket_num();
3064
3600
  const bucket_ptr old_buckets = this->priv_bucket_pointer();
3065
- this->priv_bucket_traits() = new_bucket_traits;
3066
- if(new_bucket_traits.bucket_begin() != old_buckets){
3601
+
3602
+
3603
+ this->priv_unset_sentinel_bucket();
3604
+ this->priv_initialize_new_buckets(old_buckets, old_bucket_count, new_buckets, new_bucket_count);
3605
+ if (&new_bucket_traits != &this->priv_bucket_traits())
3606
+ this->priv_bucket_traits() = new_bucket_traits;
3607
+
3608
+ if(old_buckets != new_buckets){
3067
3609
  for(size_type n = ini_n; n < split_idx; ++n){
3068
- bucket_type &new_bucket = new_bucket_traits.bucket_begin()[n];
3069
- bucket_type &old_bucket = old_buckets[n];
3070
- new_bucket.splice_after(new_bucket.cbefore_begin(), old_bucket);
3610
+ slist_node_ptr new_bucket_nodeptr = new_bucket_traits.bucket_begin()[difference_type(n)].get_node_ptr();
3611
+ slist_node_ptr old_bucket_node_ptr = old_buckets[difference_type(n)].get_node_ptr();
3612
+ slist_node_algorithms::transfer_after(new_bucket_nodeptr, old_bucket_node_ptr);
3071
3613
  }
3072
- //Put cache to safe position
3073
- this->priv_initialize_cache();
3074
- this->priv_insertion_update_cache(ini_n);
3614
+ //Reset cache to safe position
3615
+ this->priv_set_cache_bucket_num(ini_n);
3075
3616
  }
3617
+
3618
+ this->priv_set_sentinel_bucket();
3076
3619
  return true;
3077
3620
  }
3078
3621
 
@@ -3117,6 +3660,10 @@ class hashtable_impl
3117
3660
  if(constant_time_size && x.size() != y.size()){
3118
3661
  return false;
3119
3662
  }
3663
+
3664
+ if (boost::intrusive::iterator_udistance(x.begin(), x.end()) != x.size())
3665
+ return false;
3666
+
3120
3667
  for (const_iterator ix = x.cbegin(), ex = x.cend(); ix != ex; ++ix){
3121
3668
  std::pair<const_iterator, const_iterator> eqx(x.equal_range(key_of_value()(*ix))),
3122
3669
  eqy(y.equal_range(key_of_value()(*ix)));
@@ -3149,18 +3696,45 @@ class hashtable_impl
3149
3696
  BOOST_INTRUSIVE_FORCEINLINE void check() const {}
3150
3697
  private:
3151
3698
 
3152
- void rehash_impl(const bucket_traits &new_bucket_traits, bool do_full_rehash)
3699
+ static void priv_initialize_new_buckets
3700
+ ( bucket_ptr old_buckets, size_type old_bucket_count
3701
+ , bucket_ptr new_buckets, size_type new_bucket_count)
3702
+ {
3703
+ //Initialize new buckets
3704
+ const bool same_buffer = old_buckets == new_buckets;
3705
+ if (same_buffer && new_bucket_count <= old_bucket_count) {
3706
+ //Nothing to do here
3707
+ }
3708
+ else {
3709
+ bucket_ptr p;
3710
+ size_type c;
3711
+
3712
+ if (same_buffer) {
3713
+ p = old_buckets + std::ptrdiff_t(old_bucket_count);
3714
+ c = size_type(new_bucket_count - old_bucket_count);
3715
+ }
3716
+ else {
3717
+ p = new_buckets;
3718
+ c = new_bucket_count;
3719
+ }
3720
+ internal_type::priv_init_buckets(p, c);
3721
+ }
3722
+ }
3723
+
3724
+ void priv_rehash_impl(const bucket_traits &new_bucket_traits, bool do_full_rehash)
3153
3725
  {
3726
+ const std::size_t nbc = new_bucket_traits.bucket_count() - bucket_overhead;
3727
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(sizeof(SizeType) >= sizeof(std::size_t) || nbc <= SizeType(-1));
3728
+
3154
3729
  const bucket_ptr new_buckets = new_bucket_traits.bucket_begin();
3155
- size_type new_bucket_count = new_bucket_traits.bucket_count();
3730
+ const size_type new_bucket_count = static_cast<SizeType>(nbc);
3156
3731
  const bucket_ptr old_buckets = this->priv_bucket_pointer();
3157
- size_type old_bucket_count = this->bucket_count();
3732
+ const size_type old_bucket_count = this->bucket_count();
3158
3733
 
3159
3734
  //Check power of two bucket array if the option is activated
3160
3735
  BOOST_INTRUSIVE_INVARIANT_ASSERT
3161
3736
  (!power_2_buckets || (0 == (new_bucket_count & (new_bucket_count-1u))));
3162
3737
 
3163
- size_type n = this->priv_get_cache_bucket_num();
3164
3738
  const bool same_buffer = old_buckets == new_buckets;
3165
3739
  //If the new bucket length is a common factor
3166
3740
  //of the old one we can avoid hash calculations.
@@ -3169,86 +3743,95 @@ class hashtable_impl
3169
3743
  //If we are shrinking the same bucket array and it's
3170
3744
  //is a fast shrink, just rehash the last nodes
3171
3745
  size_type new_first_bucket_num = new_bucket_count;
3172
- if(same_buffer && fast_shrink && (n < new_bucket_count)){
3173
- new_first_bucket_num = n;
3174
- n = new_bucket_count;
3746
+ size_type old_bucket_cache = (size_type)this->priv_get_cache_bucket_num();
3747
+ if(same_buffer && fast_shrink && (old_bucket_cache < new_bucket_count)){
3748
+ new_first_bucket_num = old_bucket_cache;
3749
+ old_bucket_cache = new_bucket_count;
3175
3750
  }
3176
3751
 
3752
+ if (!do_full_rehash)
3753
+ this->priv_initialize_new_buckets(old_buckets, old_bucket_count, new_buckets, new_bucket_count);
3754
+
3177
3755
  //Anti-exception stuff: they destroy the elements if something goes wrong.
3178
3756
  //If the source and destination buckets are the same, the second rollback function
3179
3757
  //is harmless, because all elements have been already unlinked and destroyed
3180
- typedef detail::init_disposer<node_algorithms> NodeDisposer;
3181
- typedef detail::exception_array_disposer<bucket_type, NodeDisposer, size_type> ArrayDisposer;
3182
- NodeDisposer node_disp;
3183
- ArrayDisposer rollback1(new_buckets[0], node_disp, new_bucket_count);
3184
- ArrayDisposer rollback2(old_buckets[0], node_disp, old_bucket_count);
3758
+
3759
+ typedef typename internal_type::template typeof_node_disposer<detail::null_disposer>::type NodeDisposer;
3760
+ typedef exception_bucket_disposer<bucket_type, slist_node_algorithms, NodeDisposer, size_type> ArrayDisposer;
3761
+ NodeDisposer nd(this->make_node_disposer(detail::null_disposer()));
3762
+ ArrayDisposer rollback1(new_buckets[0], nd, new_bucket_count);
3763
+ ArrayDisposer rollback2(old_buckets[0], nd, old_bucket_count);
3185
3764
 
3186
3765
  //Put size in a safe value for rollback exception
3187
3766
  size_type const size_backup = this->priv_size_traits().get_size();
3188
3767
  this->priv_size_traits().set_size(0);
3189
3768
  //Put cache to safe position
3190
- this->priv_initialize_cache();
3191
- this->priv_insertion_update_cache(size_type(0u));
3769
+ this->priv_init_cache();
3770
+ this->priv_unset_sentinel_bucket();
3771
+
3772
+ const size_type split = this->rehash_split_from_bucket_count(new_bucket_count);
3192
3773
 
3193
3774
  //Iterate through nodes
3194
- for(; n < old_bucket_count; ++n){
3195
- bucket_type &old_bucket = old_buckets[n];
3775
+ for(size_type n = old_bucket_cache; n < old_bucket_count; ++n){
3776
+ bucket_type &old_bucket = old_buckets[difference_type(n)];
3196
3777
  if(!fast_shrink){
3197
- for( siterator before_i(old_bucket.before_begin()), i(old_bucket.begin()), end_sit(old_bucket.end())
3778
+ siterator before_i(old_bucket.get_node_ptr());
3779
+ siterator i(before_i); ++i;
3780
+ siterator end_sit(this->sit_end(old_bucket));
3781
+ for( //
3198
3782
  ; i != end_sit
3199
3783
  ; i = before_i, ++i){
3200
3784
 
3201
3785
  //First obtain hash value (and store it if do_full_rehash)
3202
3786
  std::size_t hash_value;
3203
3787
  if(do_full_rehash){
3204
- value_type &v = this->priv_value_from_slist_node(i.pointed_node());
3788
+ value_type &v = this->priv_value_from_siterator(i);
3205
3789
  hash_value = this->priv_hasher()(key_of_value()(v));
3206
- node_functions_t::store_hash(pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(v)), hash_value, store_hash_t());
3790
+ node_functions_t::store_hash(this->priv_value_to_node_ptr(v), hash_value, store_hash_t());
3207
3791
  }
3208
3792
  else{
3209
- const value_type &v = this->priv_value_from_slist_node(i.pointed_node());
3793
+ const value_type &v = this->priv_value_from_siterator(i);
3210
3794
  hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
3211
3795
  }
3212
3796
 
3213
3797
  //Now calculate the new bucket position
3214
- const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>
3215
- (hash_value, new_bucket_count, new_bucket_count);
3798
+ const size_type new_n = (size_type)hash_to_bucket_split<power_2_buckets, incremental>
3799
+ (hash_value, new_bucket_count, split, fastmod_buckets_t());
3216
3800
 
3217
3801
  //Update first used bucket cache
3218
3802
  if(cache_begin && new_n < new_first_bucket_num)
3219
3803
  new_first_bucket_num = new_n;
3220
3804
 
3221
3805
  //If the target bucket is new, transfer the whole group
3222
- siterator const last = (priv_last_in_group)(i);
3806
+ siterator last = i;
3807
+ (priv_go_to_last_in_group)(i, optimize_multikey_t());
3223
3808
 
3224
3809
  if(same_buffer && new_n == n){
3225
3810
  before_i = last;
3226
3811
  }
3227
3812
  else{
3228
- bucket_type &new_b = new_buckets[new_n];
3229
- new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
3813
+ bucket_type &new_b = new_buckets[difference_type(new_n)];
3814
+ slist_node_algorithms::transfer_after(new_b.get_node_ptr(), before_i.pointed_node(), last.pointed_node());
3230
3815
  }
3231
3816
  }
3232
3817
  }
3233
3818
  else{
3234
- const size_type new_n = detail::hash_to_bucket_split<power_2_buckets, incremental>(n, new_bucket_count, new_bucket_count);
3819
+ const size_type new_n = (size_type)hash_to_bucket_split<power_2_buckets, incremental>
3820
+ (n, new_bucket_count, split, fastmod_buckets_t());
3235
3821
  if(cache_begin && new_n < new_first_bucket_num)
3236
3822
  new_first_bucket_num = new_n;
3237
- bucket_type &new_b = new_buckets[new_n];
3238
- new_b.splice_after( new_b.before_begin()
3239
- , old_bucket
3240
- , old_bucket.before_begin()
3241
- , bucket_plus_vtraits_t::priv_get_last(old_bucket, optimize_multikey_t()));
3823
+ bucket_type &new_b = new_buckets[difference_type(new_n)];
3824
+ siterator last = this->priv_get_last(old_bucket, optimize_multikey_t());
3825
+ slist_node_algorithms::transfer_after(new_b.get_node_ptr(), old_bucket.get_node_ptr(), last.pointed_node());
3242
3826
  }
3243
3827
  }
3244
3828
 
3245
3829
  this->priv_size_traits().set_size(size_backup);
3246
- this->priv_split_traits().set_size(new_bucket_count);
3247
- if(&new_bucket_traits != &this->priv_bucket_traits()){
3830
+ this->priv_split_traits().set_size(split);
3831
+ if(&new_bucket_traits != &this->priv_bucket_traits())
3248
3832
  this->priv_bucket_traits() = new_bucket_traits;
3249
- }
3250
- this->priv_initialize_cache();
3251
- this->priv_insertion_update_cache(new_first_bucket_num);
3833
+ this->priv_set_sentinel_bucket();
3834
+ this->priv_set_cache_bucket_num(new_first_bucket_num);
3252
3835
  rollback1.release();
3253
3836
  rollback2.release();
3254
3837
  }
@@ -3283,8 +3866,8 @@ class hashtable_impl
3283
3866
  for(; b != e; ++b){
3284
3867
  //No need to check for duplicates and insert it in the first position
3285
3868
  //as this is an unordered container. So use minimal insertion code
3286
- std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t());;
3287
- size_type const bucket_number = this->priv_hash_to_bucket(hash_to_store);
3869
+ std::size_t const hash_to_store = this->priv_stored_or_compute_hash(*b, store_hash_t());
3870
+ size_type const bucket_number = this->priv_hash_to_nbucket(hash_to_store);
3288
3871
  typedef typename detail::if_c
3289
3872
  <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
3290
3873
  reference_type r = *b;
@@ -3302,16 +3885,14 @@ class hashtable_impl
3302
3885
  {
3303
3886
  //No need to check for duplicates and insert it in the first position
3304
3887
  //as this is an unordered container. So use minimal insertion code
3305
- //std::size_t const hash_value = this->priv_stored_or_compute_hash(src_ref, store_hash_t());;
3306
- //size_type const bucket_number = this->priv_hash_to_bucket(hash_value);
3307
- bucket_type &cur_bucket = this->priv_bucket_pointer()[bucket_number];
3308
- siterator const prev(cur_bucket.before_begin());
3888
+ bucket_type &cur_bucket = this->priv_bucket(bucket_number);
3889
+ siterator const prev(cur_bucket.get_node_ptr());
3309
3890
  //Just check if the cloned node is equal to the first inserted value in the new bucket
3310
3891
  //as equal src values were contiguous and they should be already inserted in the
3311
3892
  //destination bucket.
3312
- bool const next_is_in_group = optimize_multikey && !cur_bucket.empty() &&
3893
+ bool const next_is_in_group = optimize_multikey && !this->priv_bucket_empty(bucket_number) &&
3313
3894
  this->priv_equal()( key_of_value()(src_ref)
3314
- , key_of_value()(this->priv_value_from_slist_node((++siterator(prev)).pointed_node())));
3895
+ , key_of_value()(this->priv_value_from_siterator(++siterator(prev))));
3315
3896
  this->priv_insert_equal_after_find(*cloner(src_ref), bucket_number, hash_to_store, prev, next_is_in_group);
3316
3897
  }
3317
3898
 
@@ -3321,29 +3902,26 @@ class hashtable_impl
3321
3902
  //First clone the first ones
3322
3903
  const size_type src_bucket_count = src.bucket_count();
3323
3904
  const size_type dst_bucket_count = this->bucket_count();
3324
- const bucket_ptr src_buckets = src.priv_bucket_pointer();
3325
- const bucket_ptr dst_buckets = this->priv_bucket_pointer();
3326
3905
  size_type constructed = 0;
3327
- typedef node_cast_adaptor< detail::node_disposer<Disposer, value_traits, CircularSListAlgorithms>
3328
- , slist_node_ptr, node_ptr > NodeDisposer;
3906
+ typedef typename internal_type::template typeof_node_disposer<Disposer>::type NodeDisposer;
3329
3907
  NodeDisposer node_disp(disposer, &this->priv_value_traits());
3330
3908
 
3331
- detail::exception_array_disposer<bucket_type, NodeDisposer, size_type>
3332
- rollback(dst_buckets[0], node_disp, constructed);
3909
+ exception_bucket_disposer<bucket_type, slist_node_algorithms, NodeDisposer, size_type>
3910
+ rollback(this->priv_bucket(0), node_disp, constructed);
3333
3911
  //Now insert the remaining ones using the modulo trick
3334
3912
  for( //"constructed" already initialized
3335
3913
  ; constructed < src_bucket_count
3336
3914
  ; ++constructed){
3337
- //Since incremental hashing can't be structurally copied, avoid hash_to_bucket_split
3338
- const std::size_t new_n = detail::hash_to_bucket(constructed, dst_bucket_count, detail::bool_<power_2_buckets>());
3339
- bucket_type &src_b = src_buckets[constructed];
3340
- for( siterator b(src_b.begin()), e(src_b.end()); b != e; ++b){
3341
- slist_node_ptr const n(b.pointed_node());
3915
+
3916
+ const size_type new_n = (size_type)hash_to_bucket_split<power_2_buckets, incremental>
3917
+ (constructed, dst_bucket_count, this->split_count(), fastmod_buckets_t());
3918
+ bucket_type &src_b = src.priv_bucket(constructed);
3919
+ for( siterator b(this->priv_bucket_lbegin(src_b)), e(this->priv_bucket_lend(src_b)); b != e; ++b){
3342
3920
  typedef typename detail::if_c
3343
3921
  <detail::is_const<MaybeConstHashtableImpl>::value, const_reference, reference>::type reference_type;
3344
- reference_type r = this->priv_value_from_slist_node(n);
3922
+ reference_type r = this->priv_value_from_siterator(b);
3345
3923
  this->priv_clone_front_in_bucket<reference_type>
3346
- (new_n, r, this->priv_stored_hash(n, store_hash_t()), cloner);
3924
+ (new_n, r, this->priv_stored_hash(b, store_hash_t()), cloner);
3347
3925
  }
3348
3926
  }
3349
3927
  this->priv_hasher() = src.priv_hasher();
@@ -3351,78 +3929,95 @@ class hashtable_impl
3351
3929
  rollback.release();
3352
3930
  this->priv_size_traits().set_size(src.priv_size_traits().get_size());
3353
3931
  this->priv_split_traits().set_size(dst_bucket_count);
3354
- this->priv_insertion_update_cache(0u);
3932
+ this->priv_set_cache_bucket_num(0u);
3355
3933
  this->priv_erasure_update_cache();
3356
3934
  }
3357
3935
 
3358
- std::size_t priv_hash_to_bucket(std::size_t hash_value) const
3359
- {
3360
- return detail::hash_to_bucket_split<power_2_buckets, incremental>
3361
- (hash_value, this->priv_bucket_traits().bucket_count(), this->priv_split_traits().get_size());
3362
- }
3363
-
3364
3936
  iterator priv_insert_equal_after_find(reference value, size_type bucket_num, std::size_t hash_value, siterator prev, bool const next_is_in_group)
3365
3937
  {
3366
3938
  //Now store hash if needed
3367
- node_ptr n = pointer_traits<node_ptr>::pointer_to(this->priv_value_to_node(value));
3939
+ node_ptr n = this->priv_value_to_node_ptr(value);
3368
3940
  node_functions_t::store_hash(n, hash_value, store_hash_t());
3369
3941
  //Checks for some modes
3370
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || node_algorithms::unique(n));
3942
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!safemode_or_autounlink || slist_node_algorithms::unique(n));
3371
3943
  //Shortcut to optimize_multikey cases
3372
3944
  group_functions_t::insert_in_group
3373
- ( next_is_in_group ? detail::dcast_bucket_ptr<node>((++siterator(prev)).pointed_node()) : n
3945
+ ( next_is_in_group ? dcast_bucket_ptr<node>((++siterator(prev)).pointed_node()) : n
3374
3946
  , n, optimize_multikey_t());
3375
3947
  //Update cache and increment size if needed
3376
3948
  this->priv_insertion_update_cache(bucket_num);
3377
3949
  this->priv_size_traits().increment();
3378
- //Insert the element in the bucket after it
3379
- return iterator(bucket_type::s_insert_after(prev, *n), &this->get_bucket_value_traits());
3950
+ slist_node_algorithms::link_after(prev.pointed_node(), n);
3951
+ return this->build_iterator(siterator(n), this->priv_bucket_ptr(bucket_num));
3380
3952
  }
3381
3953
 
3382
3954
  template<class KeyType, class KeyHasher, class KeyEqual>
3383
- siterator priv_find //In case it is not found previt is bucket.before_begin()
3955
+ siterator priv_find //In case it is not found previt is priv_end_sit()
3384
3956
  ( const KeyType &key, KeyHasher hash_func
3385
3957
  , KeyEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
3386
3958
  {
3387
3959
  h = hash_func(key);
3388
- return this->priv_find_with_hash(key, equal_func, bucket_number, h, previt);
3389
- }
3390
3960
 
3391
- template<class KeyType, class KeyEqual>
3392
- bool priv_is_value_equal_to_key(const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func) const
3393
- {
3394
- (void)h;
3395
- return (!compare_hash || this->priv_stored_or_compute_hash(v, store_hash_t()) == h) && equal_func(key, key_of_value()(v));
3396
- }
3961
+ bucket_number = this->priv_hash_to_nbucket(h);
3962
+ bucket_type& b = this->priv_bucket(bucket_number);
3963
+ siterator prev = this->sit_bbegin(b);
3964
+ siterator it = prev;
3965
+ siterator const endit = this->sit_end(b);
3397
3966
 
3398
- //return previous iterator to the next equal range group in case
3399
- static siterator priv_last_in_group(const siterator &it_first_in_group) BOOST_NOEXCEPT
3400
- {
3401
- return bucket_type::s_iterator_to
3402
- (*group_functions_t::get_last_in_group
3403
- (detail::dcast_bucket_ptr<node>(it_first_in_group.pointed_node()), optimize_multikey_t()));
3967
+ while (++it != endit) {
3968
+ if (this->priv_is_value_equal_to_key
3969
+ (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t())) {
3970
+ previt = prev;
3971
+ return it;
3972
+ }
3973
+ (priv_go_to_last_in_group)(it, optimize_multikey_t());
3974
+ prev = it;
3975
+ }
3976
+ previt = b.get_node_ptr();
3977
+ return this->priv_end_sit();
3404
3978
  }
3405
3979
 
3980
+
3406
3981
  template<class KeyType, class KeyEqual>
3407
- siterator priv_find_with_hash //In case it is not found previt is bucket.before_begin()
3408
- ( const KeyType &key, KeyEqual equal_func, size_type &bucket_number, const std::size_t h, siterator &previt) const
3982
+ siterator priv_find_in_bucket //In case it is not found previt is priv_end_sit()
3983
+ (bucket_type &b, const KeyType& key, KeyEqual equal_func, const std::size_t h) const
3409
3984
  {
3410
- bucket_number = this->priv_hash_to_bucket(h);
3411
- bucket_type &b = this->priv_bucket_pointer()[bucket_number];
3412
- previt = b.before_begin();
3413
- siterator it = previt;
3414
- siterator const endit = b.end();
3985
+ siterator it(this->sit_begin(b));
3986
+ siterator const endit(this->sit_end(b));
3415
3987
 
3416
- while(++it != endit){
3417
- if(this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
3988
+ for (; it != endit; (priv_go_to_last_in_group)(it, optimize_multikey_t()), ++it) {
3989
+ if (BOOST_LIKELY(this->priv_is_value_equal_to_key
3990
+ (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t()))) {
3418
3991
  return it;
3419
3992
  }
3420
- previt = it = (priv_last_in_group)(it);
3421
3993
  }
3422
- previt = b.before_begin();
3423
- return this->priv_invalid_local_it();
3994
+ return this->priv_end_sit();
3995
+ }
3996
+
3997
+ template<class KeyType, class KeyEqual>
3998
+ BOOST_INTRUSIVE_FORCEINLINE bool priv_is_value_equal_to_key
3999
+ (const value_type &v, const std::size_t h, const KeyType &key, KeyEqual equal_func, detail::true_) const //compare_hash
4000
+ { return this->priv_stored_or_compute_hash(v, store_hash_t()) == h && equal_func(key, key_of_value()(v)); }
4001
+
4002
+ template<class KeyType, class KeyEqual>
4003
+ BOOST_INTRUSIVE_FORCEINLINE bool priv_is_value_equal_to_key
4004
+ (const value_type& v, const std::size_t , const KeyType& key, KeyEqual equal_func, detail::false_) const //compare_hash
4005
+ { return equal_func(key, key_of_value()(v)); }
4006
+
4007
+ //return previous iterator to the next equal range group in case
4008
+ BOOST_INTRUSIVE_FORCEINLINE static void priv_go_to_last_in_group
4009
+ (siterator &it_first_in_group, detail::true_) BOOST_NOEXCEPT //optimize_multikey
4010
+ {
4011
+ it_first_in_group =
4012
+ (group_functions_t::get_last_in_group
4013
+ (dcast_bucket_ptr<node>(it_first_in_group.pointed_node()), optimize_multikey_t()));
3424
4014
  }
3425
4015
 
4016
+ //return previous iterator to the next equal range group in case
4017
+ BOOST_INTRUSIVE_FORCEINLINE static void priv_go_to_last_in_group //!optimize_multikey
4018
+ (siterator /*&it_first_in_group*/, detail::false_) BOOST_NOEXCEPT
4019
+ { }
4020
+
3426
4021
  template<class KeyType, class KeyHasher, class KeyEqual>
3427
4022
  std::pair<siterator, siterator> priv_local_equal_range
3428
4023
  ( const KeyType &key
@@ -3431,7 +4026,7 @@ class hashtable_impl
3431
4026
  , size_type &found_bucket
3432
4027
  , size_type &cnt) const
3433
4028
  {
3434
- size_type internal_cnt = 0;
4029
+ std::size_t internal_cnt = 0;
3435
4030
  //Let's see if the element is present
3436
4031
 
3437
4032
  siterator prev;
@@ -3439,34 +4034,47 @@ class hashtable_impl
3439
4034
  std::size_t h;
3440
4035
  std::pair<siterator, siterator> to_return
3441
4036
  ( this->priv_find(key, hash_func, equal_func, n_bucket, h, prev)
3442
- , this->priv_invalid_local_it());
4037
+ , this->priv_end_sit());
3443
4038
 
3444
4039
  if(to_return.first != to_return.second){
3445
4040
  found_bucket = n_bucket;
3446
4041
  //If it's present, find the first that it's not equal in
3447
4042
  //the same bucket
3448
- bucket_type &b = this->priv_bucket_pointer()[n_bucket];
3449
4043
  siterator it = to_return.first;
3450
- ++internal_cnt; //At least one is found
3451
- if(optimize_multikey){
3452
- to_return.second = ++(priv_last_in_group)(it);
3453
- internal_cnt += boost::intrusive::iterator_distance(++it, to_return.second);
4044
+ siterator const bend = this->priv_bucket_lend(n_bucket);
4045
+ BOOST_IF_CONSTEXPR(optimize_multikey){
4046
+ siterator past_last_in_group_it = it;
4047
+ (priv_go_to_last_in_group)(past_last_in_group_it, optimize_multikey_t());
4048
+ ++past_last_in_group_it;
4049
+ internal_cnt += boost::intrusive::iterator_udistance(++it, past_last_in_group_it) + 1u;
4050
+ if (past_last_in_group_it != bend)
4051
+ to_return.second = past_last_in_group_it;
3454
4052
  }
3455
4053
  else{
3456
- siterator const bend = b.end();
3457
- while(++it != bend &&
3458
- this->priv_is_value_equal_to_key(this->priv_value_from_slist_node(it.pointed_node()), h, key, equal_func)){
3459
- ++internal_cnt;
3460
- }
3461
- to_return.second = it;
4054
+ do {
4055
+ ++internal_cnt; //At least one is found
4056
+ ++it;
4057
+ } while(it != bend &&
4058
+ this->priv_is_value_equal_to_key
4059
+ (this->priv_value_from_siterator(it), h, key, equal_func, compare_hash_t()));
4060
+ if (it != bend)
4061
+ to_return.second = it;
3462
4062
  }
3463
4063
  }
3464
- cnt = internal_cnt;
4064
+ cnt = size_type(internal_cnt);
3465
4065
  return to_return;
3466
4066
  }
3467
4067
 
4068
+ struct priv_equal_range_result
4069
+ {
4070
+ siterator first;
4071
+ siterator second;
4072
+ bucket_ptr bucket_first;
4073
+ bucket_ptr bucket_second;
4074
+ };
4075
+
3468
4076
  template<class KeyType, class KeyHasher, class KeyEqual>
3469
- std::pair<siterator, siterator> priv_equal_range
4077
+ priv_equal_range_result priv_equal_range
3470
4078
  ( const KeyType &key
3471
4079
  , KeyHasher hash_func
3472
4080
  , KeyEqual equal_func) const
@@ -3475,71 +4083,103 @@ class hashtable_impl
3475
4083
  size_type cnt;
3476
4084
 
3477
4085
  //Let's see if the element is present
3478
- std::pair<siterator, siterator> to_return
4086
+ const std::pair<siterator, siterator> to_return
3479
4087
  (this->priv_local_equal_range(key, hash_func, equal_func, n_bucket, cnt));
4088
+ priv_equal_range_result r;
4089
+ r.first = to_return.first;
4090
+ r.second = to_return.second;
4091
+
3480
4092
  //If not, find the next element as ".second" if ".second" local iterator
3481
4093
  //is not pointing to an element.
3482
- bucket_ptr const bp = this->priv_bucket_pointer();
3483
- if(to_return.first != to_return.second &&
3484
- to_return.second == bp[n_bucket].end()){
3485
- to_return.second = this->priv_invalid_local_it();
3486
- ++n_bucket;
3487
- for( const size_type max_bucket = this->bucket_count()
3488
- ; n_bucket != max_bucket
3489
- ; ++n_bucket){
3490
- bucket_type &b = bp[n_bucket];
3491
- if(!b.empty()){
3492
- to_return.second = b.begin();
3493
- break;
3494
- }
4094
+ if(to_return.first == to_return.second) {
4095
+ r.bucket_first = r.bucket_second = this->priv_invalid_bucket_ptr();
4096
+ }
4097
+ else if (to_return.second != this->priv_end_sit()) {
4098
+ r.bucket_first = this->priv_bucket_ptr(n_bucket);
4099
+ }
4100
+ else{
4101
+ r.bucket_first = this->priv_bucket_ptr(n_bucket);
4102
+ const size_type max_bucket = this->bucket_count();
4103
+ do{
4104
+ ++n_bucket;
4105
+ } while (n_bucket != max_bucket && this->priv_bucket_empty(n_bucket));
4106
+
4107
+ if (n_bucket == max_bucket){
4108
+ r.bucket_second = this->priv_invalid_bucket_ptr();
4109
+ }
4110
+ else{
4111
+ r.bucket_second = this->priv_bucket_ptr(n_bucket);
4112
+ r.second = siterator(r.bucket_second->begin_ptr());
3495
4113
  }
3496
4114
  }
3497
- return to_return;
4115
+
4116
+ return r;
3498
4117
  }
3499
4118
 
3500
- std::size_t priv_get_bucket_num(siterator it) BOOST_NOEXCEPT
3501
- { return this->priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
4119
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it) BOOST_NOEXCEPT
4120
+ { return this->priv_get_bucket_num(it, linear_buckets_t()); }
4121
+
4122
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it, detail::true_) BOOST_NOEXCEPT //linear
4123
+ { return size_type(it.get_bucket_ptr() - this->priv_bucket_pointer()); }
4124
+
4125
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num(const_iterator it, detail::false_) BOOST_NOEXCEPT //!linear
4126
+ { return this->priv_get_bucket_num_hash_dispatch(it.slist_it(), store_hash_t()); }
4127
+
4128
+ BOOST_INTRUSIVE_FORCEINLINE size_type priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) BOOST_NOEXCEPT //store_hash
4129
+ { return (size_type)this->priv_hash_to_nbucket(this->priv_stored_hash(it, store_hash_t())); }
3502
4130
 
3503
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_) BOOST_NOEXCEPT //store_hash
4131
+ size_type priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) BOOST_NOEXCEPT //NO store_hash
3504
4132
  {
3505
- return this->priv_hash_to_bucket
3506
- (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
4133
+ const bucket_type &f = this->priv_bucket(0u);
4134
+ slist_node_ptr bb = group_functions_t::get_bucket_before_begin
4135
+ ( this->priv_bucket_lbbegin(0u).pointed_node()
4136
+ , this->priv_bucket_lbbegin(this->priv_usable_bucket_count() - 1u).pointed_node()
4137
+ , it.pointed_node()
4138
+ , optimize_multikey_t());
4139
+
4140
+ //Now get the bucket_impl from the iterator
4141
+ const bucket_type &b = static_cast<const bucket_type&>(*bb);
4142
+ //Now just calculate the index b has in the bucket array
4143
+ return static_cast<size_type>(&b - &f);
3507
4144
  }
3508
4145
 
3509
- std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_) BOOST_NOEXCEPT //NO store_hash
3510
- { return this->priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
3511
4146
 
3512
- static siterator priv_get_previous(bucket_type &b, siterator i) BOOST_NOEXCEPT
3513
- { return bucket_plus_vtraits_t::priv_get_previous(b, i, optimize_multikey_t()); }
4147
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it) BOOST_NOEXCEPT
4148
+ { return this->priv_get_bucket_ptr(it, linear_buckets_t()); }
4149
+
4150
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it, detail::true_) BOOST_NOEXCEPT //linear
4151
+ { return it.get_bucket_ptr(); }
4152
+
4153
+ BOOST_INTRUSIVE_FORCEINLINE bucket_ptr priv_get_bucket_ptr(const_iterator it, detail::false_) BOOST_NOEXCEPT //!linear
4154
+ { return this->priv_bucket_ptr(this->priv_get_bucket_num_hash_dispatch(it.slist_it(), store_hash_t())); }
3514
4155
 
3515
4156
  /// @endcond
3516
4157
  };
3517
4158
 
3518
4159
  /// @cond
3519
4160
  template < class T
3520
- , bool UniqueKeys
3521
4161
  , class PackedOptions
3522
4162
  >
3523
4163
  struct make_bucket_traits
3524
4164
  {
3525
4165
  //Real value traits must be calculated from options
3526
4166
  typedef typename detail::get_value_traits
3527
- <T, typename PackedOptions::proto_value_traits>::type value_traits;
4167
+ <T, typename PackedOptions::proto_value_traits>::type value_traits;
3528
4168
 
3529
4169
  typedef typename PackedOptions::bucket_traits specified_bucket_traits;
3530
4170
 
3531
4171
  //Real bucket traits must be calculated from options and calculated value_traits
3532
- typedef typename get_slist_impl
3533
- <typename reduced_slist_node_traits
3534
- <typename value_traits::node_traits>::type
3535
- >::type slist_impl;
4172
+ typedef bucket_traits_impl
4173
+ < typename unordered_bucket_ptr_impl
4174
+ <value_traits>::type
4175
+ , std::size_t> bucket_traits_t;
3536
4176
 
3537
4177
  typedef typename
3538
4178
  detail::if_c< detail::is_same
3539
4179
  < specified_bucket_traits
3540
4180
  , default_bucket_traits
3541
4181
  >::value
3542
- , bucket_traits_impl<slist_impl>
4182
+ , bucket_traits_t
3543
4183
  , specified_bucket_traits
3544
4184
  >::type type;
3545
4185
  };
@@ -3555,6 +4195,7 @@ template<class T, class O1 = void, class O2 = void
3555
4195
  , class O5 = void, class O6 = void
3556
4196
  , class O7 = void, class O8 = void
3557
4197
  , class O9 = void, class O10= void
4198
+ , class O11= void
3558
4199
  >
3559
4200
  #endif
3560
4201
  struct make_hashtable
@@ -3563,7 +4204,7 @@ struct make_hashtable
3563
4204
  typedef typename pack_options
3564
4205
  < hashtable_defaults,
3565
4206
  #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
3566
- O1, O2, O3, O4, O5, O6, O7, O8, O9, O10
4207
+ O1, O2, O3, O4, O5, O6, O7, O8, O9, O10, O11
3567
4208
  #else
3568
4209
  Options...
3569
4210
  #endif
@@ -3573,7 +4214,7 @@ struct make_hashtable
3573
4214
  <T, typename packed_options::proto_value_traits>::type value_traits;
3574
4215
 
3575
4216
  typedef typename make_bucket_traits
3576
- <T, false, packed_options>::type bucket_traits;
4217
+ <T, packed_options>::type bucket_traits;
3577
4218
 
3578
4219
  typedef hashtable_impl
3579
4220
  < value_traits
@@ -3588,6 +4229,8 @@ struct make_hashtable
3588
4229
  |(std::size_t(packed_options::cache_begin)*hash_bool_flags::cache_begin_pos)
3589
4230
  |(std::size_t(packed_options::compare_hash)*hash_bool_flags::compare_hash_pos)
3590
4231
  |(std::size_t(packed_options::incremental)*hash_bool_flags::incremental_pos)
4232
+ |(std::size_t(packed_options::linear_buckets)*hash_bool_flags::linear_buckets_pos)
4233
+ |(std::size_t(packed_options::fastmod_buckets)*hash_bool_flags::fastmod_buckets_pos)
3591
4234
  > implementation_defined;
3592
4235
 
3593
4236
  /// @endcond